@zeyos/zx 5.0.0 → 5.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.
- package/CHANGELOG.md +164 -0
- package/README.md +2 -1
- package/dist/types/components/account-menu/account-menu.d.ts +8 -0
- package/dist/types/components/activity-list/activity-list.d.ts +9 -1
- package/dist/types/components/app-icon/app-icon.d.ts +14 -2
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +288 -14
- package/dist/types/components/calendar/calendar.d.ts +67 -5
- package/dist/types/components/card-view/card-view.d.ts +7 -4
- package/dist/types/components/card-view/record-card.d.ts +11 -0
- package/dist/types/components/context-menu/context-menu.d.ts +6 -2
- package/dist/types/components/data-filter/data-filter.d.ts +4 -4
- package/dist/types/components/dropdown/dropdown.d.ts +22 -7
- package/dist/types/components/field/field.d.ts +30 -0
- package/dist/types/components/fieldset/external-adapter.d.ts +83 -0
- package/dist/types/components/fieldset/fieldset.d.ts +7 -0
- package/dist/types/components/file-list/file-list.d.ts +35 -3
- package/dist/types/components/filter/filter.d.ts +127 -3
- package/dist/types/components/filter-panel/filter-panel.d.ts +36 -7
- package/dist/types/components/launcher/launcher.d.ts +8 -0
- package/dist/types/components/list-toolbar/list-toolbar.d.ts +15 -6
- package/dist/types/components/menu-button/menu-button.d.ts +6 -0
- package/dist/types/components/message/message.d.ts +14 -1
- package/dist/types/components/modal/modal.d.ts +30 -0
- package/dist/types/components/module-bar/module-bar.d.ts +395 -0
- package/dist/types/components/pagination/pagination.d.ts +17 -3
- package/dist/types/components/select/select.d.ts +6 -0
- package/dist/types/components/sheet/sheet.d.ts +15 -0
- package/dist/types/components/table/table.d.ts +265 -17
- package/dist/types/components/view/record-view.d.ts +59 -2
- package/dist/types/components/view-settings/view-settings.d.ts +879 -0
- package/dist/types/components/workspace-switcher/workspace-switcher.d.ts +327 -0
- package/dist/types/core/component.d.ts +12 -2
- package/dist/types/core/i18n.d.ts +27 -3
- package/dist/types/core/keyboard.d.ts +98 -1
- package/dist/types/core/messages.d.ts +382 -0
- package/dist/types/core/overlay-host.d.ts +28 -1
- package/dist/types/core/overlay-stack.d.ts +260 -0
- package/dist/types/index.d.ts +5 -2
- package/dist/types/internal/app-rail.d.ts +38 -0
- package/dist/types/internal/menu-items.d.ts +71 -3
- package/dist/types/zeyos/index.d.ts +1 -0
- package/dist/types/zeyos/launcher.d.ts +9 -0
- package/dist/types/zeyos/module-bar.d.ts +176 -0
- package/dist/types/zeyos/query.d.ts +31 -5
- package/dist/types/zeyos/table.d.ts +245 -8
- package/dist/types/zeyos/view.d.ts +16 -2
- package/dist/zx-zeyos.esm.js +4422 -430
- package/dist/zx-zeyos.esm.min.js +5 -5
- package/dist/zx.css +1417 -134
- package/dist/zx.esm.js +6986 -830
- package/dist/zx.esm.min.js +8 -8
- package/dist/zx.global.js +6986 -830
- package/dist/zx.global.min.js +8 -8
- package/dist/zx.min.css +1 -1
- package/docs/api.json +794 -17
- package/docs/llms.md +503 -63
- package/docs/llms.txt +6 -2
- package/package.json +1 -1
- package/src/components/account-menu/account-menu.js +12 -0
- package/src/components/activity-list/activity-list.js +27 -1
- package/src/components/app-icon/app-icon.css +13 -2
- package/src/components/app-icon/app-icon.js +11 -1
- package/src/components/app-rail/app-rail.css +19 -0
- package/src/components/app-sidebar/app-sidebar.css +204 -3
- package/src/components/app-sidebar/app-sidebar.js +646 -40
- package/src/components/breadcrumb/breadcrumb.css +1 -1
- package/src/components/calendar/calendar.css +1 -1
- package/src/components/calendar/calendar.js +26 -52
- package/src/components/card/card.css +2 -2
- package/src/components/card-view/card-view.css +5 -5
- package/src/components/card-view/card-view.js +13 -9
- package/src/components/card-view/record-card.js +14 -3
- package/src/components/code-editor/code-editor.css +1 -1
- package/src/components/code-editor/field-adapter.js +9 -2
- package/src/components/context-menu/context-menu.js +8 -2
- package/src/components/copy/copy-input.css +1 -1
- package/src/components/data-filter/data-filter.js +2 -2
- package/src/components/date-picker/time-picker.css +2 -2
- package/src/components/dock/dock.css +5 -4
- package/src/components/dropdown/dropdown.js +157 -72
- package/src/components/field/field.js +33 -3
- package/src/components/fieldset/external-adapter.js +363 -0
- package/src/components/fieldset/fieldset.js +10 -59
- package/src/components/file-list/file-list.js +144 -21
- package/src/components/filter/filter.css +86 -2
- package/src/components/filter/filter.js +300 -8
- package/src/components/filter-panel/filter-panel.js +149 -32
- package/src/components/finder/finder.css +1 -1
- package/src/components/kanban-view/kanban-view.css +3 -3
- package/src/components/kanban-view/kanban-view.js +5 -2
- package/src/components/launcher/launcher.css +1 -1
- package/src/components/launcher/launcher.js +29 -3
- package/src/components/list-toolbar/list-toolbar.js +39 -13
- package/src/components/master-panel/master-panel.js +0 -1
- package/src/components/menu-button/menu-button.css +63 -0
- package/src/components/menu-button/menu-button.js +97 -11
- package/src/components/message/message.js +60 -20
- package/src/components/modal/modal.css +1 -1
- package/src/components/modal/modal.js +66 -13
- package/src/components/module-bar/module-bar.css +486 -0
- package/src/components/module-bar/module-bar.js +1074 -0
- package/src/components/multi-value-editor/multi-value-editor.css +1 -1
- package/src/components/number-field/field-adapter.js +2 -1
- package/src/components/pagination/pagination.css +5 -5
- package/src/components/pagination/pagination.js +20 -4
- package/src/components/panel/panel.css +3 -2
- package/src/components/questionnaire/questionnaire.css +4 -4
- package/src/components/rating/field-adapter.js +2 -1
- package/src/components/rating/rating.css +1 -1
- package/src/components/search/search.css +4 -1
- package/src/components/select/select.js +9 -0
- package/src/components/sheet/sheet.css +1 -1
- package/src/components/sheet/sheet.js +74 -32
- package/src/components/slider/field-adapter.js +6 -1
- package/src/components/slider/slider.css +2 -2
- package/src/components/split-view/split-view.css +1 -1
- package/src/components/stat-tile/stat-tile.css +1 -1
- package/src/components/stepper/stepper.css +1 -1
- package/src/components/tabbox/tabbox.css +9 -5
- package/src/components/table/table.css +86 -11
- package/src/components/table/table.js +628 -57
- package/src/components/tag-picker/field-adapter.js +2 -1
- package/src/components/tooltip/tooltip.js +35 -17
- package/src/components/tree/tree.css +1 -1
- package/src/components/view/record-view.css +1 -1
- package/src/components/view/record-view.js +178 -18
- package/src/components/view-settings/view-settings.css +285 -0
- package/src/components/view-settings/view-settings.js +1830 -0
- package/src/components/workspace-switcher/workspace-switcher.css +188 -0
- package/src/components/workspace-switcher/workspace-switcher.js +463 -0
- package/src/core/component.js +88 -17
- package/src/core/fontawesome.js +5 -1
- package/src/core/i18n.js +47 -4
- package/src/core/icons.js +12 -2
- package/src/core/keyboard.js +206 -11
- package/src/core/messages.js +427 -0
- package/src/core/overlay-host.js +64 -9
- package/src/core/overlay-stack.js +487 -0
- package/src/core/position.js +22 -3
- package/src/index.js +5 -2
- package/src/internal/app-rail.js +134 -53
- package/src/internal/menu-items.js +61 -3
- package/src/zeyos/form.js +5 -3
- package/src/zeyos/index.js +3 -0
- package/src/zeyos/launcher.js +8 -3
- package/src/zeyos/module-bar.js +181 -0
- package/src/zeyos/query.js +44 -13
- package/src/zeyos/table.js +220 -80
- package/src/zeyos/view.js +43 -93
- package/styles/base.css +16 -1
- package/styles/print.css +1 -1
- package/styles/tokens/dark.css +4 -0
- package/styles/tokens/semantic.css +56 -28
- package/styles/zx.css +3 -0
package/src/zeyos/view.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { buildListQuery } from './query.js';
|
|
2
1
|
import { connect } from './connect.js';
|
|
3
|
-
import { normalizeZeyosListResult } from './select.js';
|
|
4
2
|
import { createSavedViewRegistry } from './saved-views.js';
|
|
5
|
-
import { buildZeyosTableConfig } from './table.js';
|
|
3
|
+
import { buildZeyosTableConfig, createServerPager } from './table.js';
|
|
6
4
|
|
|
7
5
|
/** @typedef {import('../components/view/record-view.js').ViewField} ViewField */
|
|
8
6
|
/** @typedef {import('../components/view/record-view.js').ViewSort} ViewSort */
|
|
@@ -32,7 +30,8 @@ import { buildZeyosTableConfig } from './table.js';
|
|
|
32
30
|
* calendar day their stored midnight names in it. Defaults to the runtime's own zone.
|
|
33
31
|
* @property {Record<string, Partial<ViewField>>} [fieldOverrides] View descriptor overrides.
|
|
34
32
|
* @property {string|((record:Record<string,unknown>)=>unknown)} [recordId='ID'] Record id accessor.
|
|
35
|
-
* @property {number} [pageSize=50] Server page size
|
|
33
|
+
* @property {number} [pageSize=50] Server page size, a positive integer — the same default and
|
|
34
|
+
* validation as `zeyosTable()`, because both bindings page through one shared loader.
|
|
36
35
|
* @property {ViewSort|null} [sort=null] Initial server sort.
|
|
37
36
|
* @property {Record<string, unknown>} [filters] Initial ZeyOS predicates.
|
|
38
37
|
* @property {string} [search=''] Initial full-text query.
|
|
@@ -62,7 +61,10 @@ import { buildZeyosTableConfig } from './table.js';
|
|
|
62
61
|
* @typedef {Object} ZeyosViewLoadOptions
|
|
63
62
|
* @property {string} [search] Replacement full-text query.
|
|
64
63
|
* @property {Record<string, unknown>} [filters] Replacement predicates.
|
|
65
|
-
* @property {number} [page=0] Zero-based page; pages above zero append
|
|
64
|
+
* @property {number} [page=0] Zero-based page, a non-negative integer; pages above zero append
|
|
65
|
+
* unless `replace` is set.
|
|
66
|
+
* @property {boolean} [replace] Replace the records with this page instead of appending it.
|
|
67
|
+
* @property {number} [pageSize] New page size for this and every later load.
|
|
66
68
|
*/
|
|
67
69
|
|
|
68
70
|
/**
|
|
@@ -106,6 +108,7 @@ import { buildZeyosTableConfig } from './table.js';
|
|
|
106
108
|
* @property {()=>Promise<ZeyosViewLoadResult>} loadMore Loads the next page when available.
|
|
107
109
|
* @property {number|null} count Current server count.
|
|
108
110
|
* @property {number} page Current zero-based page.
|
|
111
|
+
* @property {number} pageSize Current server page size.
|
|
109
112
|
* @property {boolean} hasMore Whether another page is available.
|
|
110
113
|
* @property {Record<string,any>|null} savedViews Saved-view registry when configured.
|
|
111
114
|
* @property {Promise<SavedViewApplyResult|null>} ready Default restoration completed before loads.
|
|
@@ -198,7 +201,17 @@ export function zeyosView(client, resource, View, opts = {}) {
|
|
|
198
201
|
}
|
|
199
202
|
}
|
|
200
203
|
const facade = connect(client);
|
|
201
|
-
|
|
204
|
+
let pager;
|
|
205
|
+
try {
|
|
206
|
+
pager = createServerPager({
|
|
207
|
+
client, facade, resource, projection: config.projection, target: view,
|
|
208
|
+
pageSize: opts.pageSize, sort: opts.sort ?? null, filters: opts.filters ?? {}, search: opts.search,
|
|
209
|
+
searchFields: opts.searchFields, label: 'ZeyOS view'
|
|
210
|
+
});
|
|
211
|
+
} catch (error) {
|
|
212
|
+
view.destroy();
|
|
213
|
+
throw error;
|
|
214
|
+
}
|
|
202
215
|
let saved;
|
|
203
216
|
try {
|
|
204
217
|
saved = resolveSavedViews(opts.savedViews, View, resource);
|
|
@@ -217,50 +230,8 @@ export function zeyosView(client, resource, View, opts = {}) {
|
|
|
217
230
|
}
|
|
218
231
|
}
|
|
219
232
|
}
|
|
220
|
-
let currentSort = opts.sort ?? null;
|
|
221
|
-
let currentFilters = copyFilters(opts.filters ?? {});
|
|
222
|
-
let currentSearch = String(opts.search ?? '');
|
|
223
|
-
let currentPage = 0;
|
|
224
|
-
let totalCount = null;
|
|
225
|
-
let more = false;
|
|
226
|
-
let requestSequence = 0;
|
|
227
233
|
let destroyed = false;
|
|
228
|
-
|
|
229
|
-
const performLoad = async (options = {}) => {
|
|
230
|
-
if (destroyed) throw new Error('ZeyOS view binding has been destroyed');
|
|
231
|
-
if (Object.prototype.hasOwnProperty.call(options, 'search')) currentSearch = String(options.search ?? '');
|
|
232
|
-
if (Object.prototype.hasOwnProperty.call(options, 'filters')) currentFilters = copyFilters(options.filters ?? {});
|
|
233
|
-
const page = normalizePage(options.page ?? 0);
|
|
234
|
-
const query = buildListQuery({
|
|
235
|
-
fields: config.projection,
|
|
236
|
-
sort: currentSort,
|
|
237
|
-
filters: currentFilters,
|
|
238
|
-
search: currentSearch,
|
|
239
|
-
searchFields: opts.searchFields,
|
|
240
|
-
limit: pageSize,
|
|
241
|
-
offset: page * pageSize,
|
|
242
|
-
count: true
|
|
243
|
-
});
|
|
244
|
-
const sequence = ++requestSequence;
|
|
245
|
-
view.setLoading(true);
|
|
246
|
-
try {
|
|
247
|
-
const normalized = normalizeZeyosListResult(client, await facade.list(resource, query));
|
|
248
|
-
const count = normalized.count ?? null;
|
|
249
|
-
const hasMore = count == null
|
|
250
|
-
? normalized.data.length === pageSize
|
|
251
|
-
: page * pageSize + normalized.data.length < count;
|
|
252
|
-
if (!destroyed && sequence === requestSequence) {
|
|
253
|
-
currentPage = page;
|
|
254
|
-
totalCount = count;
|
|
255
|
-
more = hasMore;
|
|
256
|
-
if (page === 0) view.setData(normalized.data);
|
|
257
|
-
else view.addData(normalized.data);
|
|
258
|
-
}
|
|
259
|
-
return { data: normalized.data, count, page, hasMore, query };
|
|
260
|
-
} finally {
|
|
261
|
-
if (!destroyed && sequence === requestSequence) view.setLoading(false);
|
|
262
|
-
}
|
|
263
|
-
};
|
|
234
|
+
const performLoad = pager.load;
|
|
264
235
|
|
|
265
236
|
/** @param {string} idOrName @param {{load?:boolean}} [options={}] @returns {Promise<SavedViewApplyResult>} */
|
|
266
237
|
const applySaved = async (idOrName, options = {}) => {
|
|
@@ -270,15 +241,12 @@ export function zeyosView(client, resource, View, opts = {}) {
|
|
|
270
241
|
type: presentation,
|
|
271
242
|
onQuery: async ({ filters, search }) => {
|
|
272
243
|
if (destroyed) return;
|
|
273
|
-
|
|
274
|
-
currentSearch = String(search ?? '');
|
|
244
|
+
pager.setQuery({ filters: savedFilters(filters), search });
|
|
275
245
|
}
|
|
276
246
|
});
|
|
277
247
|
if (!result.applied || destroyed) return result;
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
totalCount = null;
|
|
281
|
-
more = false;
|
|
248
|
+
pager.setSort(appliedViewSort(view, result.entry));
|
|
249
|
+
pager.reset();
|
|
282
250
|
if (options.load !== false) await performLoad({ page: 0 });
|
|
283
251
|
return result;
|
|
284
252
|
};
|
|
@@ -332,6 +300,8 @@ export function zeyosView(client, resource, View, opts = {}) {
|
|
|
332
300
|
};
|
|
333
301
|
|
|
334
302
|
const load = async (options = {}) => {
|
|
303
|
+
// Rejected before saved-view initialization runs, so an invalid call has no side effect.
|
|
304
|
+
pager.check(options);
|
|
335
305
|
await ensureInitialized({ load: false });
|
|
336
306
|
return performLoad(options);
|
|
337
307
|
};
|
|
@@ -346,8 +316,8 @@ export function zeyosView(client, resource, View, opts = {}) {
|
|
|
346
316
|
name: String(source.name ?? ''),
|
|
347
317
|
type: presentation,
|
|
348
318
|
state: view.getViewState(),
|
|
349
|
-
filters:
|
|
350
|
-
search:
|
|
319
|
+
filters: pager.filters,
|
|
320
|
+
search: pager.search
|
|
351
321
|
};
|
|
352
322
|
};
|
|
353
323
|
|
|
@@ -377,8 +347,9 @@ export function zeyosView(client, resource, View, opts = {}) {
|
|
|
377
347
|
};
|
|
378
348
|
|
|
379
349
|
const sortHandler = (event) => {
|
|
350
|
+
if (destroyed) return;
|
|
380
351
|
const id = event.detail?.id;
|
|
381
|
-
|
|
352
|
+
pager.setSort(id == null ? null : { id: String(id), dir: event.detail.dir === 'desc' ? 'desc' : 'asc' });
|
|
382
353
|
void load({ page: 0 }).catch(() => { /* connect() already reported the API failure. */ });
|
|
383
354
|
};
|
|
384
355
|
|
|
@@ -389,26 +360,12 @@ export function zeyosView(client, resource, View, opts = {}) {
|
|
|
389
360
|
setFilters: (filters) => load({ filters, page: 0 }),
|
|
390
361
|
loadMore: async () => {
|
|
391
362
|
await ensureInitialized({ load: false });
|
|
392
|
-
return
|
|
393
|
-
data: [],
|
|
394
|
-
count: totalCount,
|
|
395
|
-
page: currentPage,
|
|
396
|
-
hasMore: false,
|
|
397
|
-
query: buildListQuery({
|
|
398
|
-
fields: config.projection,
|
|
399
|
-
sort: currentSort,
|
|
400
|
-
filters: currentFilters,
|
|
401
|
-
search: currentSearch,
|
|
402
|
-
searchFields: opts.searchFields,
|
|
403
|
-
limit: pageSize,
|
|
404
|
-
offset: currentPage * pageSize,
|
|
405
|
-
count: true
|
|
406
|
-
})
|
|
407
|
-
};
|
|
363
|
+
return pager.loadMore();
|
|
408
364
|
},
|
|
409
|
-
get count() { return
|
|
410
|
-
get page() { return
|
|
411
|
-
get
|
|
365
|
+
get count() { return pager.count; },
|
|
366
|
+
get page() { return pager.page; },
|
|
367
|
+
get pageSize() { return pager.pageSize; },
|
|
368
|
+
get hasMore() { return pager.hasMore; },
|
|
412
369
|
savedViews,
|
|
413
370
|
ready,
|
|
414
371
|
restoreDefault,
|
|
@@ -418,7 +375,7 @@ export function zeyosView(client, resource, View, opts = {}) {
|
|
|
418
375
|
destroy: () => {
|
|
419
376
|
if (destroyed) return;
|
|
420
377
|
destroyed = true;
|
|
421
|
-
|
|
378
|
+
pager.destroy();
|
|
422
379
|
if (typeof view.off === 'function') view.off('sortchange', sortHandler);
|
|
423
380
|
else view.removeEventListener?.('sortchange', sortHandler);
|
|
424
381
|
if (saved?.owned) savedViews?.destroy?.();
|
|
@@ -456,21 +413,14 @@ function supplementalFieldIds(opts) {
|
|
|
456
413
|
return [...new Set(ids)];
|
|
457
414
|
}
|
|
458
415
|
|
|
459
|
-
/**
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
const number = Number(value);
|
|
468
|
-
return Number.isFinite(number) ? Math.max(0, Math.floor(number)) : 0;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
/** @param {unknown} value @returns {Record<string, unknown>} */
|
|
472
|
-
function copyFilters(value) {
|
|
473
|
-
return value && typeof value === 'object' && !Array.isArray(value) ? { ...value } : {};
|
|
416
|
+
/**
|
|
417
|
+
* Filters restored from a saved view are persisted data, not a caller's argument: a malformed
|
|
418
|
+
* entry reads as no filters rather than failing the restore.
|
|
419
|
+
* @param {unknown} value Stored filters.
|
|
420
|
+
* @returns {Record<string, unknown>}
|
|
421
|
+
*/
|
|
422
|
+
function savedFilters(value) {
|
|
423
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? { .../** @type {Record<string, unknown>} */ (value) } : {};
|
|
474
424
|
}
|
|
475
425
|
|
|
476
426
|
/**
|
package/styles/base.css
CHANGED
|
@@ -32,6 +32,20 @@
|
|
|
32
32
|
box-shadow: var(--zx-focus-ring);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/* Forced colours (Windows high contrast) drop every box-shadow, so the accent ring disappears and
|
|
36
|
+
the outline is the only focus indicator left. Components therefore never set `outline: 0` or
|
|
37
|
+
`outline: none` on a focusable element — they make it transparent (`outline-color:
|
|
38
|
+
transparent`, plus `outline-offset: -2px` where the ring is inset) and this rule paints it in a
|
|
39
|
+
system colour. `tests/lint-tokens.js` rejects outline suppression outside a marked exception.
|
|
40
|
+
`!important` because a component's own, more specific `outline-color: transparent` would
|
|
41
|
+
otherwise survive on an element that opts out with `forced-color-adjust: none` (a current item
|
|
42
|
+
filled with Highlight). Offsets are left to the component, so inset rings stay inset. */
|
|
43
|
+
@media (forced-colors: active) {
|
|
44
|
+
.zx-scope :focus-visible {
|
|
45
|
+
outline: 2px solid Highlight !important;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
35
49
|
.zx-scope ::selection {
|
|
36
50
|
background: var(--zx-color-accent);
|
|
37
51
|
color: var(--zx-color-on-accent);
|
|
@@ -129,7 +143,8 @@
|
|
|
129
143
|
}
|
|
130
144
|
|
|
131
145
|
.zx-scope .zx-icon-btn:focus-visible {
|
|
132
|
-
outline:
|
|
146
|
+
outline-color: transparent;
|
|
147
|
+
outline-offset: -2px;
|
|
133
148
|
box-shadow: inset var(--zx-focus-ring);
|
|
134
149
|
}
|
|
135
150
|
|
package/styles/print.css
CHANGED
package/styles/tokens/dark.css
CHANGED
|
@@ -84,6 +84,9 @@
|
|
|
84
84
|
--zx-color-tone-slate-fg: var(--zx-tone-slate-300);
|
|
85
85
|
--zx-color-ring: var(--zx-color-accent);
|
|
86
86
|
--zx-focus-ring: 0 0 0 3px color-mix(in srgb, var(--zx-color-ring) 45%, transparent);
|
|
87
|
+
/* The surface contact shadow keeps the light value: on a dark canvas the border, not the shadow,
|
|
88
|
+
separates a resting surface, and a heavier shadow would read as a lifted one. */
|
|
89
|
+
--zx-surface-shadow: var(--zx-shadow-1);
|
|
87
90
|
--zx-overlay-shadow: 0 12px 36px rgb(0 0 0 / 45%);
|
|
88
91
|
/* A shadow alone barely reads on a dark canvas, so the lifted item also gets a faint light rim. */
|
|
89
92
|
--zx-drag-shadow: 0 0 0 1px color-mix(in srgb, var(--zx-gray-0) 7%, transparent), 0 2px 6px -1px rgb(0 0 0 / 40%), 0 14px 32px -6px rgb(0 0 0 / 60%);
|
|
@@ -158,6 +161,7 @@
|
|
|
158
161
|
--zx-color-tone-slate-fg: var(--zx-tone-slate-300);
|
|
159
162
|
--zx-color-ring: var(--zx-color-accent);
|
|
160
163
|
--zx-focus-ring: 0 0 0 3px color-mix(in srgb, var(--zx-color-ring) 45%, transparent);
|
|
164
|
+
--zx-surface-shadow: var(--zx-shadow-1);
|
|
161
165
|
--zx-overlay-shadow: 0 12px 36px rgb(0 0 0 / 45%);
|
|
162
166
|
--zx-drag-shadow: 0 0 0 1px color-mix(in srgb, var(--zx-gray-0) 7%, transparent), 0 2px 6px -1px rgb(0 0 0 / 40%), 0 14px 32px -6px rgb(0 0 0 / 60%);
|
|
163
167
|
--zx-header-bg: var(--zx-gray-900);
|
|
@@ -12,6 +12,44 @@
|
|
|
12
12
|
* `tokens/themes.css` retheme them. Status colours keep their own ramps on purpose — see the note
|
|
13
13
|
* in that file.
|
|
14
14
|
*/
|
|
15
|
+
/*
|
|
16
|
+
* Geometry and material settings — every token here is theme-independent, so it is declared on
|
|
17
|
+
* :root ONLY and never restated on a `[data-zx-theme]` block. A custom property declared on a
|
|
18
|
+
* theme element shadows the inherited one, so a nested `[data-zx-theme="light"]` region would
|
|
19
|
+
* otherwise reset an application's own `:root { --zx-control-height: 40px }` back to the default
|
|
20
|
+
* while a dark region kept it. There is one geometry; the theme blocks below carry colours only,
|
|
21
|
+
* and `tests/unit/geometry-tokens.test.js` fails if a non-colour token moves back into one.
|
|
22
|
+
*/
|
|
23
|
+
:root {
|
|
24
|
+
--zx-control-height: 30px;
|
|
25
|
+
--zx-control-pad-x: 10px;
|
|
26
|
+
--zx-control-radius: var(--zx-radius-lg);
|
|
27
|
+
--zx-control-font-size: var(--zx-text-md);
|
|
28
|
+
--zx-control-font-weight: 500;
|
|
29
|
+
/* Blur applied behind a backdrop that asked for it. */
|
|
30
|
+
--zx-overlay-blur: 8px;
|
|
31
|
+
/* AppIcon is a dark chromatic lens: colour lives in its rim and low bloom, not a glossy fill.
|
|
32
|
+
Its strengths remain inherited, while each AppIcon mixes them with its own module colour. */
|
|
33
|
+
--zx-app-icon-core-strength: 52%;
|
|
34
|
+
--zx-app-icon-rim-strength: 58%;
|
|
35
|
+
--zx-app-icon-bloom-strength: 64%;
|
|
36
|
+
--zx-app-icon-specular-strength: 72%;
|
|
37
|
+
--zx-app-icon-halo-size: 14px;
|
|
38
|
+
--zx-app-icon-halo-strength: 22%;
|
|
39
|
+
--zx-overlay-specular-strength: 48%;
|
|
40
|
+
--zx-glass-blur: 8px;
|
|
41
|
+
--zx-glass-saturation: 130%;
|
|
42
|
+
--zx-glass-color-strength: 82%;
|
|
43
|
+
/* Material filters are roles, not component recipes. Aurora remains a separate canvas layer. */
|
|
44
|
+
--zx-glass-filter-icon: blur(4px) saturate(118%);
|
|
45
|
+
--zx-glass-filter-control: blur(6px) saturate(116%);
|
|
46
|
+
--zx-glass-filter-raised: blur(8px) saturate(120%);
|
|
47
|
+
--zx-glass-filter-chrome: blur(10px) saturate(122%);
|
|
48
|
+
--zx-glass-filter-overlay: blur(16px) saturate(140%);
|
|
49
|
+
--zx-glass-filter-panel: blur(14px) saturate(132%);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* The light theme — colours only. */
|
|
15
53
|
:root,
|
|
16
54
|
[data-zx-theme="light"] {
|
|
17
55
|
color-scheme: light;
|
|
@@ -80,41 +118,30 @@
|
|
|
80
118
|
--zx-color-chart-6: var(--zx-tone-green-500);
|
|
81
119
|
--zx-color-chart-7: var(--zx-tone-violet-500);
|
|
82
120
|
--zx-color-chart-8: var(--zx-tone-red-500);
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
--zx-
|
|
87
|
-
--zx-
|
|
121
|
+
/* Solid identity fills — a module tile, an application icon — carrying the white icon glyph.
|
|
122
|
+
The 500 stops keep that glyph at 3:1 or better and read as the same tone on either theme,
|
|
123
|
+
so, like the chart series, the dark theme keeps this list. */
|
|
124
|
+
--zx-color-tone-blue-solid: var(--zx-tone-blue-500);
|
|
125
|
+
--zx-color-tone-teal-solid: var(--zx-tone-teal-500);
|
|
126
|
+
--zx-color-tone-green-solid: var(--zx-tone-green-500);
|
|
127
|
+
--zx-color-tone-amber-solid: var(--zx-tone-amber-500);
|
|
128
|
+
--zx-color-tone-orange-solid: var(--zx-tone-orange-500);
|
|
129
|
+
--zx-color-tone-red-solid: var(--zx-tone-red-500);
|
|
130
|
+
--zx-color-tone-pink-solid: var(--zx-tone-pink-500);
|
|
131
|
+
--zx-color-tone-violet-solid: var(--zx-tone-violet-500);
|
|
132
|
+
--zx-color-tone-slate-solid: var(--zx-tone-slate-500);
|
|
133
|
+
/* A resting surface one hair off what it sits on — a panel, an outlined card in a lane, a slider
|
|
134
|
+
thumb: a contact shadow only, far below an overlay or a dragged item. */
|
|
135
|
+
--zx-surface-shadow: var(--zx-shadow-1);
|
|
88
136
|
--zx-overlay-shadow: var(--zx-shadow-3);
|
|
89
137
|
/* An item being dragged — a lifted card, a row in flight, a drag preview: a tight contact
|
|
90
138
|
shadow and a wide soft one, clearly higher than a resting card and lower than an overlay. */
|
|
91
139
|
--zx-drag-shadow: 0 2px 4px -1px color-mix(in srgb, var(--zx-gray-950) 10%, transparent),
|
|
92
140
|
0 12px 28px -6px color-mix(in srgb, var(--zx-gray-950) 22%, transparent);
|
|
93
|
-
/* Blur applied behind a backdrop that asked for it. Theme-independent, so light defines it once. */
|
|
94
|
-
--zx-overlay-blur: 8px;
|
|
95
141
|
--zx-color-glass-border: color-mix(in srgb, var(--zx-gray-0) 24%, transparent);
|
|
96
142
|
--zx-color-glass-highlight: color-mix(in srgb, var(--zx-gray-0) 24%, transparent);
|
|
97
143
|
--zx-color-glass-highlight-strong: color-mix(in srgb, var(--zx-gray-0) 38%, transparent);
|
|
98
|
-
/* AppIcon is a dark chromatic lens: colour lives in its rim and low bloom, not a glossy fill. */
|
|
99
|
-
/* Strengths remain inherited, while each AppIcon mixes them with its own module colour. */
|
|
100
|
-
--zx-app-icon-core-strength: 52%;
|
|
101
|
-
--zx-app-icon-rim-strength: 58%;
|
|
102
|
-
--zx-app-icon-bloom-strength: 64%;
|
|
103
|
-
--zx-app-icon-specular-strength: 72%;
|
|
104
|
-
--zx-app-icon-halo-size: 14px;
|
|
105
|
-
--zx-app-icon-halo-strength: 22%;
|
|
106
144
|
--zx-color-overlay-backdrop: color-mix(in srgb, var(--zx-gray-950) 28%, transparent);
|
|
107
|
-
--zx-overlay-specular-strength: 48%;
|
|
108
|
-
--zx-glass-blur: 8px;
|
|
109
|
-
--zx-glass-saturation: 130%;
|
|
110
|
-
--zx-glass-color-strength: 82%;
|
|
111
|
-
/* Material filters are roles, not component recipes. Aurora remains a separate canvas layer. */
|
|
112
|
-
--zx-glass-filter-icon: blur(4px) saturate(118%);
|
|
113
|
-
--zx-glass-filter-control: blur(6px) saturate(116%);
|
|
114
|
-
--zx-glass-filter-raised: blur(8px) saturate(120%);
|
|
115
|
-
--zx-glass-filter-chrome: blur(10px) saturate(122%);
|
|
116
|
-
--zx-glass-filter-overlay: blur(16px) saturate(140%);
|
|
117
|
-
--zx-glass-filter-panel: blur(14px) saturate(132%);
|
|
118
145
|
--zx-glass-control-shadow: inset 0 1px 0 color-mix(in srgb, var(--zx-gray-0) 18%, transparent), var(--zx-shadow-1);
|
|
119
146
|
--zx-glass-chrome-shadow: inset 0 1px 0 color-mix(in srgb, var(--zx-gray-0) 16%, transparent), var(--zx-shadow-1);
|
|
120
147
|
--zx-header-bg: var(--zx-gray-900);
|
|
@@ -126,8 +153,9 @@
|
|
|
126
153
|
* tone tints — are restated on every theme element, not only on :root. A custom property is
|
|
127
154
|
* resolved where it is declared and inherited as a finished value, so a dark region on a light
|
|
128
155
|
* page would otherwise inherit light glass and light overlays. The dark theme, which loads later,
|
|
129
|
-
* overrides the ones it derives differently. Geometry and the base palette stay on :root
|
|
130
|
-
* application's own overrides there still
|
|
156
|
+
* overrides the ones it derives differently. Geometry and the base palette stay on :root (the block
|
|
157
|
+
* at the top of this file and tokens/global.css), so an application's own overrides there still
|
|
158
|
+
* reach nested regions.
|
|
131
159
|
*/
|
|
132
160
|
:root,
|
|
133
161
|
[data-zx-theme] {
|
package/styles/zx.css
CHANGED
|
@@ -37,7 +37,9 @@
|
|
|
37
37
|
@import url("../src/components/activity-item/activity-item.css");
|
|
38
38
|
@import url("../src/components/activity-list/activity-list.css");
|
|
39
39
|
@import url("../src/components/account-menu/account-menu.css");
|
|
40
|
+
@import url("../src/components/workspace-switcher/workspace-switcher.css");
|
|
40
41
|
@import url("../src/components/app-rail/app-rail.css");
|
|
42
|
+
@import url("../src/components/module-bar/module-bar.css");
|
|
41
43
|
@import url("../src/components/app-sidebar/app-sidebar.css");
|
|
42
44
|
@import url("../src/components/message/message.css");
|
|
43
45
|
@import url("../src/components/modal/modal.css");
|
|
@@ -68,6 +70,7 @@
|
|
|
68
70
|
@import url("../src/components/stat-tile/stat-tile.css");
|
|
69
71
|
@import url("../src/components/card-view/card-view.css");
|
|
70
72
|
@import url("../src/components/kanban-view/kanban-view.css");
|
|
73
|
+
@import url("../src/components/view-settings/view-settings.css");
|
|
71
74
|
@import url("../src/components/grid/grid.css");
|
|
72
75
|
@import url("../src/components/chart/chart.css");
|
|
73
76
|
@import url("../src/components/tree/tree.css");
|