@incursa/ui-kit 1.0.0 → 1.2.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.
Files changed (45) hide show
  1. package/AI-AGENT-INSTRUCTIONS.md +42 -28
  2. package/LLMS.txt +56 -40
  3. package/README.md +190 -73
  4. package/dist/inc-design-language.css +430 -247
  5. package/dist/inc-design-language.css.map +1 -1
  6. package/dist/inc-design-language.js +520 -0
  7. package/dist/inc-design-language.min.css +1 -1
  8. package/dist/inc-design-language.min.css.map +1 -1
  9. package/dist/web-components/README.md +92 -0
  10. package/dist/web-components/RUNTIME-NOTES.md +40 -0
  11. package/dist/web-components/base-element.js +193 -0
  12. package/dist/web-components/components/feedback.js +1074 -0
  13. package/dist/web-components/components/forms.js +979 -0
  14. package/dist/web-components/components/layout.js +408 -0
  15. package/dist/web-components/components/navigation.js +854 -0
  16. package/dist/web-components/components/overlays.js +634 -0
  17. package/dist/web-components/controllers/focus.js +101 -0
  18. package/dist/web-components/controllers/overlay.js +128 -0
  19. package/dist/web-components/controllers/selection.js +145 -0
  20. package/dist/web-components/controllers/theme.js +173 -0
  21. package/dist/web-components/index.js +886 -0
  22. package/dist/web-components/package.json +3 -0
  23. package/dist/web-components/registry.js +74 -0
  24. package/dist/web-components/shared.js +186 -0
  25. package/dist/web-components/style.css +6 -0
  26. package/package.json +16 -4
  27. package/src/inc-design-language.js +520 -0
  28. package/src/inc-design-language.scss +456 -257
  29. package/src/web-components/README.md +92 -0
  30. package/src/web-components/RUNTIME-NOTES.md +40 -0
  31. package/src/web-components/base-element.js +193 -0
  32. package/src/web-components/components/feedback.js +1074 -0
  33. package/src/web-components/components/forms.js +979 -0
  34. package/src/web-components/components/layout.js +408 -0
  35. package/src/web-components/components/navigation.js +854 -0
  36. package/src/web-components/components/overlays.js +634 -0
  37. package/src/web-components/controllers/focus.js +101 -0
  38. package/src/web-components/controllers/overlay.js +128 -0
  39. package/src/web-components/controllers/selection.js +145 -0
  40. package/src/web-components/controllers/theme.js +173 -0
  41. package/src/web-components/index.js +886 -0
  42. package/src/web-components/package.json +3 -0
  43. package/src/web-components/registry.js +74 -0
  44. package/src/web-components/shared.js +186 -0
  45. package/src/web-components/style.css +6 -0
@@ -0,0 +1,408 @@
1
+ /* eslint-disable max-classes-per-file */
2
+ (function (root, factory) {
3
+ if (typeof module === "object" && module.exports) {
4
+ module.exports = factory();
5
+ return;
6
+ }
7
+
8
+ const exports = factory();
9
+ root.IncWebComponents = root.IncWebComponents || {};
10
+ root.IncWebComponents.layout = exports;
11
+ }(typeof globalThis !== "undefined" ? globalThis : window, function () {
12
+ "use strict";
13
+
14
+ const BOOLEAN_ATTRIBUTE_TYPES = new Set(["boolean"]);
15
+ const HTMLElementRef = typeof HTMLElement === "undefined" ? null : HTMLElement;
16
+ const MutationObserverRef = typeof MutationObserver === "undefined" ? null : MutationObserver;
17
+ const BaseElement = HTMLElementRef || class {};
18
+
19
+ function toBooleanAttribute(value) {
20
+ return value === true || value === "" || value === "true";
21
+ }
22
+
23
+ function tokenList(value) {
24
+ if (!value) {
25
+ return [];
26
+ }
27
+
28
+ return String(value)
29
+ .split(/\s+/u)
30
+ .map((part) => part.trim())
31
+ .filter(Boolean);
32
+ }
33
+
34
+ function dispatchSlotChange(host) {
35
+ host.dispatchEvent(new Event("slotchange"));
36
+ }
37
+
38
+ class IncLayoutElement extends BaseElement {
39
+ static get observedAttributes() {
40
+ return this.layoutConfig ? Object.keys(this.layoutConfig.attributes || {}) : [];
41
+ }
42
+
43
+ constructor() {
44
+ super();
45
+ this._mutationObserver = null;
46
+ this._syncQueued = false;
47
+ this._appliedTokenClasses = new Map();
48
+ this._appliedBooleanClasses = new Map();
49
+ this._appliedIntegerClasses = new Map();
50
+ }
51
+
52
+ connectedCallback() {
53
+ this._applyHostClasses();
54
+ this._syncChildren();
55
+
56
+ if (!MutationObserverRef) {
57
+ return;
58
+ }
59
+
60
+ if (!this._mutationObserver) {
61
+ this._mutationObserver = new MutationObserverRef(() => this._queueSync());
62
+ }
63
+
64
+ this._mutationObserver.observe(this, {
65
+ childList: true,
66
+ attributes: true,
67
+ subtree: false,
68
+ attributeFilter: ["slot"],
69
+ });
70
+ }
71
+
72
+ disconnectedCallback() {
73
+ if (this._mutationObserver) {
74
+ this._mutationObserver.disconnect();
75
+ }
76
+ }
77
+
78
+ attributeChangedCallback() {
79
+ this._applyHostClasses();
80
+ this._queueSync();
81
+ }
82
+
83
+ _queueSync() {
84
+ if (this._syncQueued) {
85
+ return;
86
+ }
87
+
88
+ this._syncQueued = true;
89
+ queueMicrotask(() => {
90
+ this._syncQueued = false;
91
+ this._syncChildren();
92
+ dispatchSlotChange(this);
93
+ });
94
+ }
95
+
96
+ _applyHostClasses() {
97
+ const config = this.constructor.layoutConfig || {};
98
+ const hostClasses = [config.baseClass, ...(config.hostClasses || [])].filter(Boolean);
99
+
100
+ this.classList.add(...hostClasses);
101
+
102
+ const parts = tokenList(config.parts);
103
+ if (parts.length) {
104
+ this.setAttribute("part", parts.join(" "));
105
+ }
106
+
107
+ const attributes = config.attributes || {};
108
+ Object.entries(attributes).forEach(([name, meta]) => {
109
+ const value = this.getAttribute(name);
110
+ const baseClass = config.baseClass;
111
+ const hostClassPrefix = meta.classPrefix || (baseClass ? `${baseClass}--` : "");
112
+
113
+ if (meta.type === "token") {
114
+ const values = tokenList(value);
115
+ const appliedKey = `${name}:token`;
116
+ const previousClasses = this._appliedTokenClasses.get(appliedKey) || [];
117
+ previousClasses.forEach((className) => this.classList.remove(className));
118
+
119
+ const nextClasses = values.map((token) => `${hostClassPrefix}${token}`);
120
+ nextClasses.forEach((className) => this.classList.add(className));
121
+ this._appliedTokenClasses.set(appliedKey, nextClasses);
122
+ return;
123
+ }
124
+
125
+ if (BOOLEAN_ATTRIBUTE_TYPES.has(meta.type)) {
126
+ const enabled = toBooleanAttribute(value);
127
+ const onClass = meta.trueClass || `${baseClass}--${name}`;
128
+ const offClass = meta.falseClass;
129
+
130
+ const appliedKey = `${name}:boolean`;
131
+ const previousClasses = this._appliedBooleanClasses.get(appliedKey) || [];
132
+ previousClasses.forEach((className) => this.classList.remove(className));
133
+
134
+ const nextClasses = [];
135
+ if (this.hasAttribute(name)) {
136
+ if (enabled && onClass) {
137
+ nextClasses.push(onClass);
138
+ } else if (!enabled && offClass) {
139
+ nextClasses.push(offClass);
140
+ }
141
+ }
142
+
143
+ nextClasses.forEach((className) => this.classList.add(className));
144
+ this._appliedBooleanClasses.set(appliedKey, nextClasses);
145
+ return;
146
+ }
147
+
148
+ if (meta.type === "integer" && name === "columns") {
149
+ const parsed = Number.parseInt(value || "", 10);
150
+ const appliedKey = `${name}:integer`;
151
+ const previousClasses = this._appliedIntegerClasses.get(appliedKey) || [];
152
+ previousClasses.forEach((className) => this.classList.remove(className));
153
+
154
+ if (Number.isInteger(parsed) && parsed > 0) {
155
+ this.style.setProperty("--inc-summary-columns", String(parsed));
156
+ const nextClasses = [`${baseClass}--${parsed}-col`];
157
+ nextClasses.forEach((className) => this.classList.add(className));
158
+ this._appliedIntegerClasses.set(appliedKey, nextClasses);
159
+ return;
160
+ }
161
+
162
+ this.style.removeProperty("--inc-summary-columns");
163
+ this._appliedIntegerClasses.set(appliedKey, []);
164
+ }
165
+ });
166
+ }
167
+
168
+ _syncChildren() {
169
+ const config = this.constructor.layoutConfig || {};
170
+ const slotClasses = config.slotClasses || {};
171
+ const managedClasses = new Set(Object.values(slotClasses));
172
+
173
+ Array.from(this.children).forEach((child) => {
174
+ if (!HTMLElementRef || !(child instanceof HTMLElementRef)) {
175
+ return;
176
+ }
177
+
178
+ managedClasses.forEach((className) => {
179
+ child.classList.remove(className);
180
+ });
181
+
182
+ const slotName = child.getAttribute("slot");
183
+ const slotClass = slotClasses[slotName] || null;
184
+ if (slotClass) {
185
+ child.classList.add(slotClass);
186
+ }
187
+ });
188
+ }
189
+ }
190
+
191
+ function defineLayoutAccessors(ComponentClass) {
192
+ const config = ComponentClass.layoutConfig || {};
193
+ const attributes = config.attributes || {};
194
+
195
+ Object.entries(attributes).forEach(([attributeName, meta]) => {
196
+ if (Object.prototype.hasOwnProperty.call(ComponentClass.prototype, attributeName)) {
197
+ return;
198
+ }
199
+
200
+ Object.defineProperty(ComponentClass.prototype, attributeName, {
201
+ configurable: true,
202
+ enumerable: true,
203
+ get() {
204
+ if (meta.type === "boolean") {
205
+ return this.hasAttribute(attributeName);
206
+ }
207
+
208
+ if (meta.type === "integer") {
209
+ const value = Number.parseInt(this.getAttribute(attributeName) || "", 10);
210
+ return Number.isNaN(value) ? null : value;
211
+ }
212
+
213
+ return this.getAttribute(attributeName);
214
+ },
215
+ set(value) {
216
+ if (meta.type === "boolean") {
217
+ if (value) {
218
+ this.setAttribute(attributeName, "");
219
+ } else {
220
+ this.removeAttribute(attributeName);
221
+ }
222
+ return;
223
+ }
224
+
225
+ if (value === null || value === undefined || value === "") {
226
+ this.removeAttribute(attributeName);
227
+ return;
228
+ }
229
+
230
+ this.setAttribute(attributeName, String(value));
231
+ },
232
+ });
233
+ });
234
+ }
235
+
236
+ class IncAppShellElement extends IncLayoutElement {}
237
+ IncAppShellElement.layoutConfig = {
238
+ baseClass: "inc-app-shell",
239
+ parts: "shell header main footer",
240
+ attributes: {
241
+ variant: { type: "token" },
242
+ dense: { type: "boolean" },
243
+ collapsed: { type: "boolean" },
244
+ },
245
+ slotClasses: {
246
+ header: "inc-app-shell__header",
247
+ main: "inc-app-shell__main",
248
+ footer: "inc-app-shell__footer",
249
+ },
250
+ };
251
+
252
+ class IncPageElement extends IncLayoutElement {}
253
+ IncPageElement.layoutConfig = {
254
+ baseClass: "inc-page",
255
+ parts: "page breadcrumbs body aside footer",
256
+ attributes: {
257
+ variant: { type: "token" },
258
+ dense: { type: "boolean" },
259
+ wide: { type: "boolean" },
260
+ },
261
+ slotClasses: {
262
+ breadcrumbs: "inc-page__breadcrumbs",
263
+ header: "inc-page__header",
264
+ body: "inc-page__body",
265
+ aside: "inc-page__aside",
266
+ footer: "inc-page__footer",
267
+ },
268
+ };
269
+
270
+ class IncPageHeaderElement extends IncLayoutElement {}
271
+ IncPageHeaderElement.layoutConfig = {
272
+ baseClass: "inc-page-header",
273
+ parts: "header title body actions",
274
+ attributes: {
275
+ variant: { type: "token" },
276
+ dense: { type: "boolean" },
277
+ },
278
+ slotClasses: {
279
+ title: "inc-page-header__title",
280
+ body: "inc-page-header__body",
281
+ actions: "inc-page-header__actions",
282
+ },
283
+ };
284
+
285
+ class IncSectionElement extends IncLayoutElement {}
286
+ IncSectionElement.layoutConfig = {
287
+ baseClass: "inc-section-container",
288
+ hostClasses: ["inc-section"],
289
+ parts: "section header body footer actions",
290
+ attributes: {
291
+ variant: { type: "token", classPrefix: "inc-section--" },
292
+ dense: { type: "boolean", trueClass: "inc-section--dense" },
293
+ tone: { type: "token", classPrefix: "inc-section--tone-" },
294
+ },
295
+ slotClasses: {
296
+ header: "inc-section__header",
297
+ body: "inc-section__body",
298
+ footer: "inc-section__footer",
299
+ actions: "inc-section__actions",
300
+ },
301
+ };
302
+
303
+ class IncCardElement extends IncLayoutElement {}
304
+ IncCardElement.layoutConfig = {
305
+ baseClass: "inc-card",
306
+ parts: "card header body footer",
307
+ attributes: {
308
+ variant: { type: "token" },
309
+ tone: { type: "token", classPrefix: "inc-card--tone-" },
310
+ elevated: { type: "boolean", trueClass: "inc-card--elevated" },
311
+ },
312
+ slotClasses: {
313
+ header: "inc-card__header",
314
+ body: "inc-card__body",
315
+ footer: "inc-card__footer",
316
+ },
317
+ };
318
+
319
+ class IncSummaryOverviewElement extends IncLayoutElement {}
320
+ IncSummaryOverviewElement.layoutConfig = {
321
+ baseClass: "inc-summary-overview",
322
+ parts: "overview",
323
+ attributes: {
324
+ columns: { type: "integer" },
325
+ dense: { type: "boolean" },
326
+ },
327
+ slotClasses: {},
328
+ };
329
+
330
+ class IncSummaryBlockElement extends IncLayoutElement {}
331
+ IncSummaryBlockElement.layoutConfig = {
332
+ baseClass: "inc-summary-block",
333
+ parts: "block header body footer actions value status",
334
+ attributes: {
335
+ variant: { type: "token" },
336
+ tone: { type: "token", classPrefix: "inc-summary-block--tone-" },
337
+ dense: { type: "boolean" },
338
+ },
339
+ slotClasses: {
340
+ header: "inc-summary-block__header",
341
+ body: "inc-summary-block__body",
342
+ footer: "inc-summary-block__footer",
343
+ actions: "inc-summary-block__actions",
344
+ },
345
+ };
346
+
347
+ class IncFooterBarElement extends IncLayoutElement {}
348
+ IncFooterBarElement.layoutConfig = {
349
+ baseClass: "inc-footer-bar",
350
+ parts: "footer menu meta",
351
+ attributes: {
352
+ variant: { type: "token" },
353
+ dense: { type: "boolean" },
354
+ },
355
+ slotClasses: {
356
+ menu: "inc-footer-bar__menu",
357
+ meta: "inc-footer-bar__meta",
358
+ },
359
+ };
360
+
361
+ const layoutComponents = [
362
+ ["inc-app-shell", IncAppShellElement],
363
+ ["inc-page", IncPageElement],
364
+ ["inc-page-header", IncPageHeaderElement],
365
+ ["inc-section", IncSectionElement],
366
+ ["inc-card", IncCardElement],
367
+ ["inc-summary-overview", IncSummaryOverviewElement],
368
+ ["inc-summary-block", IncSummaryBlockElement],
369
+ ["inc-footer-bar", IncFooterBarElement],
370
+ ];
371
+
372
+ layoutComponents.forEach(([, ComponentClass]) => {
373
+ defineLayoutAccessors(ComponentClass);
374
+ });
375
+
376
+ function defineLayoutComponents(registry) {
377
+ const targetRegistry = registry || (typeof customElements !== "undefined" ? customElements : null);
378
+
379
+ if (!targetRegistry) {
380
+ return [];
381
+ }
382
+
383
+ const defined = [];
384
+ layoutComponents.forEach(([tagName, ComponentClass]) => {
385
+ if (targetRegistry.get(tagName)) {
386
+ return;
387
+ }
388
+
389
+ targetRegistry.define(tagName, ComponentClass);
390
+ defined.push(tagName);
391
+ });
392
+
393
+ return defined;
394
+ }
395
+
396
+ return {
397
+ IncAppShellElement,
398
+ IncPageElement,
399
+ IncPageHeaderElement,
400
+ IncSectionElement,
401
+ IncCardElement,
402
+ IncSummaryOverviewElement,
403
+ IncSummaryBlockElement,
404
+ IncFooterBarElement,
405
+ layoutComponents,
406
+ defineLayoutComponents,
407
+ };
408
+ }));