@incursa/ui-kit 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +8 -0
- package/README.md +18 -0
- package/dist/icons/index.js +371 -0
- package/dist/icons/package.json +3 -0
- package/dist/inc-design-language.css +115 -1
- package/dist/inc-design-language.css.map +1 -1
- package/dist/inc-design-language.js +1558 -1462
- package/dist/inc-design-language.min.css +1 -1
- package/dist/inc-design-language.min.css.map +1 -1
- package/dist/mcp/components/cards.json +3 -3
- package/dist/mcp/components/metrics.json +3 -3
- package/dist/mcp/components/states.json +3 -3
- package/dist/mcp/examples/data-grid-advanced.json +2 -2
- package/dist/mcp/examples/demo.json +2 -2
- package/dist/mcp/examples/overlay-workflows.json +2 -2
- package/dist/mcp/examples/reference.json +2 -2
- package/dist/mcp/examples/states.json +2 -2
- package/dist/mcp/examples/web-components.json +2 -2
- package/dist/mcp/guides/allowed-web-component-families.json +2 -2
- package/dist/mcp/guides/latest.json +2 -2
- package/dist/mcp/guides/package-metadata.json +2 -2
- package/dist/mcp/guides/update.json +2 -2
- package/dist/mcp/install.json +1 -1
- package/dist/mcp/patterns/data-grid-advanced.json +2 -2
- package/dist/mcp/patterns/demo.json +2 -2
- package/dist/mcp/patterns/overlay-workflows.json +2 -2
- package/dist/mcp/patterns/reference.json +2 -2
- package/dist/mcp/patterns/states.json +2 -2
- package/dist/mcp/patterns/web-components.json +2 -2
- package/dist/mcp/resources.json +81 -78
- package/dist/mcp/search-index.json +22 -22
- package/dist/mcp/update.json +2 -2
- package/dist/mcp/worker.mjs +331 -286
- package/dist/mcp/worker.mjs.map +2 -2
- package/dist/web-components/README.md +7 -0
- package/dist/web-components/RUNTIME-NOTES.md +2 -0
- package/dist/web-components/components/actions.js +149 -2
- package/dist/web-components/components/feedback.js +63 -12
- package/dist/web-components/components/visualizations.js +629 -0
- package/dist/web-components/index.js +3642 -139
- package/package.json +13 -3
- package/src/icons/index.js +229 -0
- package/src/icons/package.json +3 -0
- package/src/inc-design-language.js +12 -11
- package/src/inc-design-language.scss +132 -1
- package/src/web-components/README.md +7 -0
- package/src/web-components/RUNTIME-NOTES.md +2 -0
- package/src/web-components/components/actions.js +149 -2
- package/src/web-components/components/feedback.js +63 -12
- package/src/web-components/components/visualizations.js +629 -0
- package/src/web-components/index.js +8 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@incursa/ui-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Reusable UI kit for data-heavy business applications.",
|
|
6
6
|
"keywords": [
|
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
"style": "./dist/web-components/style.css",
|
|
34
34
|
"default": "./dist/web-components/index.js"
|
|
35
35
|
},
|
|
36
|
+
"./icons": {
|
|
37
|
+
"default": "./dist/icons/index.js"
|
|
38
|
+
},
|
|
36
39
|
"./web-components/style.css": "./dist/web-components/style.css",
|
|
37
40
|
"./dist/inc-design-language.css": "./dist/inc-design-language.css",
|
|
38
41
|
"./dist/inc-design-language.min.css": "./dist/inc-design-language.min.css",
|
|
@@ -52,11 +55,12 @@
|
|
|
52
55
|
"scripts": {
|
|
53
56
|
"build:css": "sass --load-path=node_modules --quiet-deps --silence-deprecation=import src/inc-design-language.scss dist/inc-design-language.css --style=expanded",
|
|
54
57
|
"build:css:min": "sass --load-path=node_modules --quiet-deps --silence-deprecation=import src/inc-design-language.scss dist/inc-design-language.min.css --style=compressed",
|
|
55
|
-
"build:
|
|
58
|
+
"build:icons": "node scripts/build-icons.mjs",
|
|
59
|
+
"build:js": "esbuild src/inc-design-language.js --bundle --format=iife --platform=browser --outfile=dist/inc-design-language.js",
|
|
56
60
|
"build:wc": "node scripts/build-web-components.mjs",
|
|
57
61
|
"build:mcp:manifests": "node scripts/generate-mcp.mjs",
|
|
58
62
|
"build:mcp": "node scripts/build-mcp.mjs",
|
|
59
|
-
"build": "npm run build:css && npm run build:css:min && npm run build:js && npm run build:wc && npm run build:mcp",
|
|
63
|
+
"build": "npm run build:icons && npm run build:css && npm run build:css:min && npm run build:js && npm run build:wc && npm run build:mcp",
|
|
60
64
|
"test:browser:install": "playwright install chromium",
|
|
61
65
|
"test:browser": "playwright test",
|
|
62
66
|
"test:mcp": "node --test tests/mcp/transport.test.mjs tests/mcp/search.test.mjs tests/mcp/installation.test.mjs tests/mcp/markup.test.mjs tests/mcp/freshness.test.mjs",
|
|
@@ -70,6 +74,12 @@
|
|
|
70
74
|
"pack:tarball": "npm pack",
|
|
71
75
|
"package": "npm run build && npm run smoke && npm run pack:tarball"
|
|
72
76
|
},
|
|
77
|
+
"dependencies": {
|
|
78
|
+
"d3-array": "^3.2.4",
|
|
79
|
+
"d3-scale": "^4.0.2",
|
|
80
|
+
"d3-shape": "^3.2.0",
|
|
81
|
+
"lucide": "^1.17.0"
|
|
82
|
+
},
|
|
73
83
|
"devDependencies": {
|
|
74
84
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
75
85
|
"@playwright/test": "^1.58.2",
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import createLucideElement from "lucide/dist/esm/createElement.mjs";
|
|
2
|
+
import CircleCheck from "lucide/dist/esm/icons/circle-check.mjs";
|
|
3
|
+
import CircleHelp from "lucide/dist/esm/icons/circle-question-mark.mjs";
|
|
4
|
+
import CircleX from "lucide/dist/esm/icons/circle-x.mjs";
|
|
5
|
+
import Download from "lucide/dist/esm/icons/download.mjs";
|
|
6
|
+
import ExternalLink from "lucide/dist/esm/icons/external-link.mjs";
|
|
7
|
+
import FileText from "lucide/dist/esm/icons/file-text.mjs";
|
|
8
|
+
import FolderPlus from "lucide/dist/esm/icons/folder-plus.mjs";
|
|
9
|
+
import Info from "lucide/dist/esm/icons/info.mjs";
|
|
10
|
+
import Lock from "lucide/dist/esm/icons/lock.mjs";
|
|
11
|
+
import Pause from "lucide/dist/esm/icons/pause.mjs";
|
|
12
|
+
import Play from "lucide/dist/esm/icons/play.mjs";
|
|
13
|
+
import RefreshCw from "lucide/dist/esm/icons/refresh-cw.mjs";
|
|
14
|
+
import SearchX from "lucide/dist/esm/icons/search-x.mjs";
|
|
15
|
+
import Settings from "lucide/dist/esm/icons/settings.mjs";
|
|
16
|
+
import ShieldCheck from "lucide/dist/esm/icons/shield-check.mjs";
|
|
17
|
+
import TriangleAlert from "lucide/dist/esm/icons/triangle-alert.mjs";
|
|
18
|
+
import Upload from "lucide/dist/esm/icons/upload.mjs";
|
|
19
|
+
|
|
20
|
+
const ICON_NODES = Object.freeze({
|
|
21
|
+
info: Info,
|
|
22
|
+
help: CircleHelp,
|
|
23
|
+
success: CircleCheck,
|
|
24
|
+
warning: TriangleAlert,
|
|
25
|
+
error: CircleX,
|
|
26
|
+
upload: Upload,
|
|
27
|
+
document: FileText,
|
|
28
|
+
download: Download,
|
|
29
|
+
settings: Settings,
|
|
30
|
+
"external-link": ExternalLink,
|
|
31
|
+
empty: FolderPlus,
|
|
32
|
+
"no-results": SearchX,
|
|
33
|
+
loading: RefreshCw,
|
|
34
|
+
lock: Lock,
|
|
35
|
+
pause: Pause,
|
|
36
|
+
play: Play,
|
|
37
|
+
permission: ShieldCheck,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const ICON_NAMES = Object.freeze(Object.keys(ICON_NODES));
|
|
41
|
+
const DEFAULT_SIZE = 16;
|
|
42
|
+
|
|
43
|
+
function getNamespace() {
|
|
44
|
+
if (typeof globalThis === "undefined") {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const root = globalThis.IncWebComponents || (globalThis.IncWebComponents = {});
|
|
49
|
+
const icons = root.icons || (root.icons = {});
|
|
50
|
+
|
|
51
|
+
if (!icons.names) {
|
|
52
|
+
icons.names = ICON_NAMES;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!icons.defaultRenderer) {
|
|
56
|
+
icons.defaultRenderer = renderDefaultIcon;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!icons.render) {
|
|
60
|
+
icons.render = renderIncIcon;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (!icons.setRenderer) {
|
|
64
|
+
icons.setRenderer = setIconRenderer;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return icons;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function normalizeIconName(name) {
|
|
71
|
+
return String(name || "")
|
|
72
|
+
.trim()
|
|
73
|
+
.toLowerCase()
|
|
74
|
+
.replace(/[_\s]+/g, "-");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function normalizeSize(value) {
|
|
78
|
+
const parsed = Number.parseFloat(value);
|
|
79
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_SIZE;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function buildIconAttributes(name, options = {}) {
|
|
83
|
+
const size = normalizeSize(options.size);
|
|
84
|
+
const className = options.className || "inc-icon";
|
|
85
|
+
const attrs = {
|
|
86
|
+
width: size,
|
|
87
|
+
height: size,
|
|
88
|
+
"data-inc-icon": name,
|
|
89
|
+
class: className,
|
|
90
|
+
focusable: "false",
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
if (options.decorative !== false) {
|
|
94
|
+
attrs["aria-hidden"] = "true";
|
|
95
|
+
} else {
|
|
96
|
+
attrs.role = "img";
|
|
97
|
+
attrs["aria-label"] = options.label || name;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return attrs;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function renderDefaultIcon(name, options = {}) {
|
|
104
|
+
const normalizedName = normalizeIconName(name);
|
|
105
|
+
const iconNode = ICON_NODES[normalizedName] || ICON_NODES.info;
|
|
106
|
+
|
|
107
|
+
if (typeof document === "undefined") {
|
|
108
|
+
return "";
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return createLucideElement(iconNode, buildIconAttributes(normalizedName, options));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function coerceIconResult(result) {
|
|
115
|
+
if (!result || typeof document === "undefined") {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (result instanceof Node) {
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (typeof result === "string") {
|
|
124
|
+
const template = document.createElement("template");
|
|
125
|
+
template.innerHTML = result.trim();
|
|
126
|
+
return template.content.firstElementChild || null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function getIconRenderer() {
|
|
133
|
+
const namespace = getNamespace();
|
|
134
|
+
return typeof namespace?.renderer === "function"
|
|
135
|
+
? namespace.renderer
|
|
136
|
+
: renderDefaultIcon;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function setIconRenderer(renderer) {
|
|
140
|
+
const namespace = getNamespace();
|
|
141
|
+
if (!namespace) {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (renderer == null) {
|
|
146
|
+
delete namespace.renderer;
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (typeof renderer !== "function") {
|
|
151
|
+
throw new TypeError("Inc icon renderer must be a function.");
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
namespace.renderer = renderer;
|
|
155
|
+
return renderer;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function renderIncIcon(name, options = {}) {
|
|
159
|
+
const normalizedName = normalizeIconName(name) || "info";
|
|
160
|
+
const renderer = getIconRenderer();
|
|
161
|
+
const rendered = renderer(normalizedName, options);
|
|
162
|
+
const icon = coerceIconResult(rendered) || coerceIconResult(renderDefaultIcon(normalizedName, options));
|
|
163
|
+
|
|
164
|
+
if (icon instanceof Element && options.decorative !== false) {
|
|
165
|
+
icon.setAttribute("aria-hidden", "true");
|
|
166
|
+
icon.removeAttribute("aria-label");
|
|
167
|
+
icon.removeAttribute("role");
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return icon;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function replaceIconContents(container, name, options = {}) {
|
|
174
|
+
if (!(container instanceof Element)) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
container.replaceChildren();
|
|
179
|
+
const icon = renderIncIcon(name, options);
|
|
180
|
+
if (icon) {
|
|
181
|
+
icon.setAttribute("data-inc-generated-icon", "true");
|
|
182
|
+
icon.setAttribute("data-inc-icon-upgraded", "true");
|
|
183
|
+
container.append(icon);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return icon;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function upgradeIconPlaceholders(root = typeof document !== "undefined" ? document : null) {
|
|
190
|
+
if (!root || typeof root.querySelectorAll !== "function") {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const upgraded = [];
|
|
195
|
+
root.querySelectorAll("[data-inc-icon]").forEach((node) => {
|
|
196
|
+
if (!(node instanceof Element)) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const name = node.getAttribute("data-inc-icon");
|
|
201
|
+
if (!name || node.hasAttribute("data-inc-icon-upgraded") || node.hasAttribute("data-inc-generated-icon")) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
replaceIconContents(node, name, {
|
|
206
|
+
className: node.getAttribute("data-inc-icon-class") || "inc-icon",
|
|
207
|
+
decorative: node.getAttribute("aria-hidden") !== "false",
|
|
208
|
+
label: node.getAttribute("aria-label") || undefined,
|
|
209
|
+
size: node.getAttribute("data-inc-icon-size") || undefined,
|
|
210
|
+
});
|
|
211
|
+
node.setAttribute("data-inc-icon-upgraded", "true");
|
|
212
|
+
upgraded.push(node);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
return upgraded;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
getNamespace();
|
|
219
|
+
|
|
220
|
+
export {
|
|
221
|
+
ICON_NAMES as incIconNames,
|
|
222
|
+
getIconRenderer,
|
|
223
|
+
normalizeIconName,
|
|
224
|
+
renderDefaultIcon,
|
|
225
|
+
renderIncIcon,
|
|
226
|
+
replaceIconContents,
|
|
227
|
+
setIconRenderer,
|
|
228
|
+
upgradeIconPlaceholders,
|
|
229
|
+
};
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
replaceIconContents,
|
|
3
|
+
upgradeIconPlaceholders,
|
|
4
|
+
} from "./icons/index.js";
|
|
5
|
+
|
|
1
6
|
(function () {
|
|
2
7
|
"use strict";
|
|
3
8
|
|
|
@@ -12,6 +17,7 @@
|
|
|
12
17
|
themeLabel: "[data-inc-theme-label]",
|
|
13
18
|
themeSwitcher: "[data-inc-theme-switcher], details.inc-theme-switcher",
|
|
14
19
|
nativeDialogOpen: "[data-inc-native-dialog-open]",
|
|
20
|
+
icon: "[data-inc-icon]",
|
|
15
21
|
autoRefresh: "[data-inc-auto-refresh]",
|
|
16
22
|
autoRefreshToggle: '[data-inc-action="auto-refresh-toggle"]',
|
|
17
23
|
fileExample: "[data-inc-file-example]",
|
|
@@ -1132,16 +1138,6 @@
|
|
|
1132
1138
|
return `${minutes}m ${seconds}s`;
|
|
1133
1139
|
}
|
|
1134
1140
|
|
|
1135
|
-
const AUTO_REFRESH_PAUSE_ICON = `
|
|
1136
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
|
1137
|
-
<path d="M4 3h3v10H4zM9 3h3v10H9z"></path>
|
|
1138
|
-
</svg>`.trim();
|
|
1139
|
-
|
|
1140
|
-
const AUTO_REFRESH_PLAY_ICON = `
|
|
1141
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
|
1142
|
-
<path d="M4 3.5v9l8-4.5-8-4.5z"></path>
|
|
1143
|
-
</svg>`.trim();
|
|
1144
|
-
|
|
1145
1141
|
function getAutoRefreshParts(root) {
|
|
1146
1142
|
const toggle = root.querySelector(".inc-auto-refresh__toggle");
|
|
1147
1143
|
|
|
@@ -1183,7 +1179,11 @@
|
|
|
1183
1179
|
}
|
|
1184
1180
|
|
|
1185
1181
|
if (parts.toggleIcon instanceof HTMLElement) {
|
|
1186
|
-
parts.toggleIcon
|
|
1182
|
+
replaceIconContents(parts.toggleIcon, isPaused ? "play" : "pause", {
|
|
1183
|
+
className: "inc-icon",
|
|
1184
|
+
decorative: true,
|
|
1185
|
+
size: 16,
|
|
1186
|
+
});
|
|
1187
1187
|
}
|
|
1188
1188
|
}
|
|
1189
1189
|
|
|
@@ -1848,6 +1848,7 @@
|
|
|
1848
1848
|
initializeMenus();
|
|
1849
1849
|
initializeCollapses();
|
|
1850
1850
|
initializeTabs();
|
|
1851
|
+
upgradeIconPlaceholders(document);
|
|
1851
1852
|
initializeFileExamples();
|
|
1852
1853
|
initializeAutoRefresh();
|
|
1853
1854
|
attachEventHandlers();
|
|
@@ -448,6 +448,12 @@
|
|
|
448
448
|
// Buttons, badges, alerts, and form primitives
|
|
449
449
|
// -----------------------------------------------------------------------------
|
|
450
450
|
|
|
451
|
+
.inc-icon {
|
|
452
|
+
display: block;
|
|
453
|
+
flex: 0 0 auto;
|
|
454
|
+
stroke: currentColor;
|
|
455
|
+
}
|
|
456
|
+
|
|
451
457
|
.inc-btn {
|
|
452
458
|
@extend .btn;
|
|
453
459
|
display: inline-flex;
|
|
@@ -457,6 +463,15 @@
|
|
|
457
463
|
vertical-align: middle;
|
|
458
464
|
transition: color 0.18s ease, background-color 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
|
|
459
465
|
|
|
466
|
+
&__icon {
|
|
467
|
+
display: inline-flex;
|
|
468
|
+
align-items: center;
|
|
469
|
+
justify-content: center;
|
|
470
|
+
width: 1rem;
|
|
471
|
+
height: 1rem;
|
|
472
|
+
flex: 0 0 auto;
|
|
473
|
+
}
|
|
474
|
+
|
|
460
475
|
&--primary {
|
|
461
476
|
@extend .btn-primary;
|
|
462
477
|
}
|
|
@@ -736,6 +751,17 @@
|
|
|
736
751
|
@extend .alert-dismissible;
|
|
737
752
|
}
|
|
738
753
|
|
|
754
|
+
&__icon {
|
|
755
|
+
display: inline-flex;
|
|
756
|
+
align-items: center;
|
|
757
|
+
justify-content: center;
|
|
758
|
+
width: 1.125rem;
|
|
759
|
+
height: 1.125rem;
|
|
760
|
+
margin-inline-end: 0.5rem;
|
|
761
|
+
vertical-align: -0.2em;
|
|
762
|
+
color: currentColor;
|
|
763
|
+
}
|
|
764
|
+
|
|
739
765
|
&__heading {
|
|
740
766
|
@extend .alert-heading;
|
|
741
767
|
}
|
|
@@ -1175,6 +1201,12 @@
|
|
|
1175
1201
|
display: inline-flex;
|
|
1176
1202
|
align-items: center;
|
|
1177
1203
|
justify-content: center;
|
|
1204
|
+
|
|
1205
|
+
svg {
|
|
1206
|
+
display: block;
|
|
1207
|
+
width: 2.125rem;
|
|
1208
|
+
height: 2.125rem;
|
|
1209
|
+
}
|
|
1178
1210
|
}
|
|
1179
1211
|
|
|
1180
1212
|
&__form {
|
|
@@ -3238,7 +3270,6 @@ dialog.inc-native-dialog.inc-native-dialog--drawer .inc-native-dialog__body {
|
|
|
3238
3270
|
display: block;
|
|
3239
3271
|
width: 1rem;
|
|
3240
3272
|
height: 1rem;
|
|
3241
|
-
fill: currentColor;
|
|
3242
3273
|
}
|
|
3243
3274
|
}
|
|
3244
3275
|
|
|
@@ -3363,6 +3394,100 @@ dialog.inc-native-dialog.inc-native-dialog--drawer .inc-native-dialog__body {
|
|
|
3363
3394
|
}
|
|
3364
3395
|
}
|
|
3365
3396
|
|
|
3397
|
+
.inc-sparkline {
|
|
3398
|
+
--inc-sparkline-stroke: var(--inc-text-secondary);
|
|
3399
|
+
--inc-sparkline-fill: rgba(var(--inc-text-secondary-rgb), 0.12);
|
|
3400
|
+
--inc-sparkline-marker: var(--inc-sparkline-stroke);
|
|
3401
|
+
--inc-sparkline-reference: rgba(var(--inc-text-muted-rgb), 0.68);
|
|
3402
|
+
--inc-sparkline-muted: rgba(var(--inc-text-muted-rgb), 0.54);
|
|
3403
|
+
display: inline-flex;
|
|
3404
|
+
align-items: center;
|
|
3405
|
+
justify-content: center;
|
|
3406
|
+
inline-size: var(--inc-sparkline-width, 7.5rem);
|
|
3407
|
+
block-size: var(--inc-sparkline-height, 2rem);
|
|
3408
|
+
min-inline-size: 1rem;
|
|
3409
|
+
min-block-size: 1rem;
|
|
3410
|
+
vertical-align: middle;
|
|
3411
|
+
color: var(--inc-sparkline-stroke);
|
|
3412
|
+
contain: paint;
|
|
3413
|
+
|
|
3414
|
+
&--tone-positive {
|
|
3415
|
+
--inc-sparkline-stroke: var(--bs-success);
|
|
3416
|
+
--inc-sparkline-fill: rgba(var(--bs-success-rgb), 0.16);
|
|
3417
|
+
--inc-sparkline-marker: var(--bs-success-text-emphasis);
|
|
3418
|
+
}
|
|
3419
|
+
|
|
3420
|
+
&--tone-negative {
|
|
3421
|
+
--inc-sparkline-stroke: var(--bs-danger);
|
|
3422
|
+
--inc-sparkline-fill: rgba(var(--bs-danger-rgb), 0.14);
|
|
3423
|
+
--inc-sparkline-marker: var(--bs-danger-text-emphasis);
|
|
3424
|
+
}
|
|
3425
|
+
|
|
3426
|
+
&--tone-muted {
|
|
3427
|
+
--inc-sparkline-stroke: var(--inc-text-muted);
|
|
3428
|
+
--inc-sparkline-fill: rgba(var(--inc-text-muted-rgb), 0.1);
|
|
3429
|
+
--inc-sparkline-marker: var(--inc-text-secondary);
|
|
3430
|
+
}
|
|
3431
|
+
|
|
3432
|
+
&--tone-accent {
|
|
3433
|
+
--inc-sparkline-stroke: var(--bs-primary);
|
|
3434
|
+
--inc-sparkline-fill: rgba(var(--bs-primary-rgb), 0.14);
|
|
3435
|
+
--inc-sparkline-marker: var(--bs-primary);
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3438
|
+
&__svg {
|
|
3439
|
+
display: block;
|
|
3440
|
+
inline-size: 100%;
|
|
3441
|
+
block-size: 100%;
|
|
3442
|
+
overflow: visible;
|
|
3443
|
+
}
|
|
3444
|
+
|
|
3445
|
+
&__line,
|
|
3446
|
+
&__empty-line {
|
|
3447
|
+
fill: none;
|
|
3448
|
+
stroke: var(--inc-sparkline-stroke);
|
|
3449
|
+
stroke-width: 1.6;
|
|
3450
|
+
stroke-linecap: round;
|
|
3451
|
+
stroke-linejoin: round;
|
|
3452
|
+
}
|
|
3453
|
+
|
|
3454
|
+
&__area {
|
|
3455
|
+
fill: var(--inc-sparkline-fill);
|
|
3456
|
+
stroke: none;
|
|
3457
|
+
}
|
|
3458
|
+
|
|
3459
|
+
&__bar {
|
|
3460
|
+
fill: var(--inc-sparkline-stroke);
|
|
3461
|
+
opacity: 0.82;
|
|
3462
|
+
}
|
|
3463
|
+
|
|
3464
|
+
&__marker {
|
|
3465
|
+
fill: var(--inc-sparkline-marker);
|
|
3466
|
+
stroke: var(--inc-surface-primary);
|
|
3467
|
+
stroke-width: 1.5;
|
|
3468
|
+
}
|
|
3469
|
+
|
|
3470
|
+
&__reference {
|
|
3471
|
+
stroke: var(--inc-sparkline-reference);
|
|
3472
|
+
stroke-width: 1;
|
|
3473
|
+
stroke-dasharray: 3 3;
|
|
3474
|
+
}
|
|
3475
|
+
|
|
3476
|
+
&__empty-line {
|
|
3477
|
+
stroke: var(--inc-sparkline-muted);
|
|
3478
|
+
stroke-dasharray: 2 4;
|
|
3479
|
+
}
|
|
3480
|
+
|
|
3481
|
+
&__empty {
|
|
3482
|
+
fill: var(--inc-text-muted);
|
|
3483
|
+
font-family: $font-family-sans-serif;
|
|
3484
|
+
font-size: 0.625rem;
|
|
3485
|
+
font-weight: 600;
|
|
3486
|
+
letter-spacing: 0;
|
|
3487
|
+
pointer-events: none;
|
|
3488
|
+
}
|
|
3489
|
+
}
|
|
3490
|
+
|
|
3366
3491
|
.inc-alert-container {
|
|
3367
3492
|
@extend .container-xxl;
|
|
3368
3493
|
position: relative;
|
|
@@ -4644,6 +4769,12 @@ body.inc-offcanvas-open {
|
|
|
4644
4769
|
font-size: 1.25rem;
|
|
4645
4770
|
font-weight: 700;
|
|
4646
4771
|
flex: 0 0 auto;
|
|
4772
|
+
|
|
4773
|
+
svg {
|
|
4774
|
+
display: block;
|
|
4775
|
+
width: 1.375rem;
|
|
4776
|
+
height: 1.375rem;
|
|
4777
|
+
}
|
|
4647
4778
|
}
|
|
4648
4779
|
|
|
4649
4780
|
&__title {
|
|
@@ -8,9 +8,11 @@ The CSS-first [`inc-*`](../../reference.html) class surface remains the canonica
|
|
|
8
8
|
|
|
9
9
|
- Package entrypoint: `@incursa/ui-kit/web-components`
|
|
10
10
|
- Style entrypoint: `@incursa/ui-kit/web-components/style.css`
|
|
11
|
+
- Icon entrypoint: `@incursa/ui-kit/icons`
|
|
11
12
|
- Built output: `dist/web-components/`
|
|
12
13
|
- Package export: `./web-components` resolves to `dist/web-components/index.js`
|
|
13
14
|
- Package export: `./web-components/style.css` resolves to `dist/web-components/style.css`
|
|
15
|
+
- Package export: `./icons` resolves to `dist/icons/index.js`
|
|
14
16
|
- Module boundary: `src/web-components/package.json` sets this subtree to `type: module`
|
|
15
17
|
|
|
16
18
|
Load these entrypoints only when the consuming app wants the custom elements and their default look. CSS-only consumers should not pay for the runtime.
|
|
@@ -45,6 +47,8 @@ The runtime auto-defines the shipped elements on load. If a consumer needs expli
|
|
|
45
47
|
The `IncElement` base class, including reflected attribute/property wiring and slot helpers.
|
|
46
48
|
- [`registry.js`](registry.js)
|
|
47
49
|
Idempotent registration helpers and the `IncWebComponents.registry` namespace.
|
|
50
|
+
- [`../icons/index.js`](../icons/index.js)
|
|
51
|
+
Semantic Incursa icon names, default Lucide-backed rendering, and the global renderer override used by component fallbacks.
|
|
48
52
|
- [`components/dom-helpers.js`](components/dom-helpers.js)
|
|
49
53
|
Shared DOM helpers used by the action and collection modules.
|
|
50
54
|
- [`controllers/focus.js`](controllers/focus.js)
|
|
@@ -67,6 +71,8 @@ The runtime auto-defines the shipped elements on load. If a consumer needs expli
|
|
|
67
71
|
Button, button-group, button-toolbar, close-button, alert, and empty-state custom elements.
|
|
68
72
|
- [`components/collections.js`](components/collections.js)
|
|
69
73
|
List-group, key-value-grid, and key-value custom elements.
|
|
74
|
+
- [`components/visualizations.js`](components/visualizations.js)
|
|
75
|
+
D3-backed sparkline custom element and small path/data helpers.
|
|
70
76
|
- [`components/overlays.js`](components/overlays.js)
|
|
71
77
|
Disclosure, dialog, and drawer custom elements.
|
|
72
78
|
- [`index.js`](index.js)
|
|
@@ -82,6 +88,7 @@ The Web Component layer should mirror the current CSS kit, not reinterpret it.
|
|
|
82
88
|
- Form wrappers should keep native controls native.
|
|
83
89
|
- Navigation components should reflect keyboard and focus state in the DOM.
|
|
84
90
|
- Feedback and status shells should announce state accessibly, badge/spinner atoms should standardize the common tone and loading defaults, and action/detail plus collection hosts should keep buttons, alerts, list groups, and description-list pairs declarative without inventing a second styling vocabulary.
|
|
91
|
+
- Visualization components should stay compact, accessible, and evidence-supporting. Use D3 for geometry and scales, not DOM mutation.
|
|
85
92
|
- Overlays should prefer native `<details>` and `<dialog>` behavior when that satisfies the contract.
|
|
86
93
|
- Tables, data presentation, utility atoms, and the remaining presentation-only surfaces should remain CSS-first until the component contract is explicit and worth the runtime cost.
|
|
87
94
|
|
|
@@ -12,6 +12,7 @@ The runtime defines the approved v1 host family set:
|
|
|
12
12
|
- feedback and status: `inc-state-panel`, `inc-live-region`, `inc-auto-refresh`, `inc-theme-switcher`, `inc-badge`, `inc-spinner`
|
|
13
13
|
- actions and detail shells: `inc-button`, `inc-button-group`, `inc-button-toolbar`, `inc-close-button`, `inc-alert`, `inc-empty-state`
|
|
14
14
|
- collections: `inc-list-group`, `inc-key-value-grid`, `inc-key-value`
|
|
15
|
+
- data visualization: `inc-sparkline`
|
|
15
16
|
- overlays: `inc-disclosure`, `inc-dialog`, `inc-drawer`
|
|
16
17
|
|
|
17
18
|
## Contract shape
|
|
@@ -28,6 +29,7 @@ The runtime defines the approved v1 host family set:
|
|
|
28
29
|
- `components/feedback.js`
|
|
29
30
|
- `components/actions.js`
|
|
30
31
|
- `components/collections.js`
|
|
32
|
+
- `components/visualizations.js`
|
|
31
33
|
- `components/overlays.js`
|
|
32
34
|
- Public registration API is idempotent:
|
|
33
35
|
- `window.IncWebComponents.defineAll()`
|