@zeyos/zx 4.4.0 → 5.0.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 +283 -0
- package/README.md +42 -10
- package/dist/types/components/activity-list/activity-list.d.ts +22 -0
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +5 -3
- package/dist/types/components/avatar/avatar.d.ts +46 -7
- package/dist/types/components/badge/badge.d.ts +21 -1
- package/dist/types/components/button/button.d.ts +15 -0
- package/dist/types/components/chart/chart.d.ts +10 -0
- package/dist/types/components/checklist/checklist.d.ts +9 -0
- package/dist/types/components/code-editor/code-editor.d.ts +6 -17
- package/dist/types/components/datebox/date-range-box.d.ts +5 -1
- package/dist/types/components/datebox/datebox.d.ts +7 -2
- package/dist/types/components/dialog/dialog.d.ts +46 -6
- package/dist/types/components/dropdown/dropdown.d.ts +2 -2
- package/dist/types/components/entity-ref/entity-ref.d.ts +2 -2
- package/dist/types/components/field/field.d.ts +24 -2
- package/dist/types/components/fieldset/fieldset.d.ts +19 -1
- package/dist/types/components/file-item/file-item.d.ts +34 -6
- package/dist/types/components/form/form.d.ts +12 -1
- package/dist/types/components/kanban-view/kanban-card.d.ts +8 -0
- package/dist/types/components/launcher/launcher.d.ts +260 -15
- package/dist/types/components/list-toolbar/list-toolbar.d.ts +1 -1
- package/dist/types/components/menu-button/menu-button.d.ts +33 -5
- package/dist/types/components/message/message.d.ts +119 -17
- package/dist/types/components/modal/modal.d.ts +13 -2
- package/dist/types/components/select/color.d.ts +12 -0
- package/dist/types/components/select/glyphs.d.ts +124 -0
- package/dist/types/components/select/select.d.ts +11 -3
- package/dist/types/components/stat-tile/stat-tile.d.ts +16 -5
- package/dist/types/components/tabbox/tabbox.d.ts +9 -0
- package/dist/types/components/table/table.d.ts +46 -1
- package/dist/types/components/tag-picker/tag-picker.d.ts +21 -4
- package/dist/types/components/tree/tree.d.ts +13 -0
- package/dist/types/core/breakpoint.d.ts +1 -1
- package/dist/types/core/icons.d.ts +23 -25
- package/dist/types/core/motion.d.ts +59 -0
- package/dist/types/core/overlay-host.d.ts +15 -1
- package/dist/types/index.d.ts +5 -3
- package/dist/types/zeyos/connect.d.ts +6 -0
- package/dist/types/zeyos/form.d.ts +50 -9
- package/dist/types/zeyos/index.d.ts +1 -1
- package/dist/types/zeyos/query.d.ts +79 -0
- package/dist/types/zeyos/schema.d.ts +24 -1
- package/dist/types/zeyos/table.d.ts +100 -14
- package/dist/types/zeyos/view.d.ts +10 -0
- package/dist/zx-zeyos.esm.js +1621 -443
- package/dist/zx-zeyos.esm.min.js +53 -5
- package/dist/zx.css +1411 -660
- package/dist/zx.esm.js +1976 -703
- package/dist/zx.esm.min.js +56 -8
- package/dist/zx.global.js +1978 -705
- package/dist/zx.global.min.js +56 -8
- package/dist/zx.min.css +1 -1
- package/docs/api.json +219 -34
- package/docs/llms.md +472 -110
- package/docs/llms.txt +3 -3
- package/package.json +1 -1
- package/src/components/account-menu/account-menu.css +35 -10
- package/src/components/activity-item/activity-item.css +1 -1
- package/src/components/activity-item/activity-item.js +3 -0
- package/src/components/activity-list/activity-list.css +38 -3
- package/src/components/activity-list/activity-list.js +34 -0
- package/src/components/app-icon/app-icon.css +1 -1
- package/src/components/app-rail/app-rail.css +40 -79
- package/src/components/app-sidebar/app-sidebar.css +109 -174
- package/src/components/app-sidebar/app-sidebar.js +21 -6
- package/src/components/aurora/aurora.css +5 -3
- package/src/components/avatar/avatar.css +32 -7
- package/src/components/avatar/avatar.js +72 -8
- package/src/components/badge/badge.css +54 -2
- package/src/components/badge/badge.js +29 -2
- package/src/components/button/button.css +67 -9
- package/src/components/button/button.js +38 -0
- package/src/components/calendar/calendar.css +46 -46
- package/src/components/card/card.css +2 -2
- package/src/components/card-view/card-view.css +9 -7
- package/src/components/chart/chart.css +4 -1
- package/src/components/chart/chart.js +12 -0
- package/src/components/check-button/check-button.css +10 -2
- package/src/components/checklist/checklist.css +9 -2
- package/src/components/checklist/checklist.js +11 -5
- package/src/components/checklist/field-adapter.js +3 -1
- package/src/components/code-editor/code-editor.css +6 -5
- package/src/components/code-editor/code-editor.js +19 -1
- package/src/components/context-menu/context-menu.css +9 -4
- package/src/components/copy/copy-button.css +6 -0
- package/src/components/copy/copy-input.css +8 -3
- package/src/components/data-filter/data-filter.css +5 -4
- package/src/components/date-picker/date-picker.css +6 -6
- package/src/components/date-picker/date-range-picker.css +3 -3
- package/src/components/date-picker/time-picker.css +1 -1
- package/src/components/datebox/date-range-box.css +79 -2
- package/src/components/datebox/date-range-box.js +13 -2
- package/src/components/datebox/datebox.css +79 -2
- package/src/components/datebox/datebox.js +13 -2
- package/src/components/dialog/dialog.css +26 -0
- package/src/components/dialog/dialog.js +99 -17
- package/src/components/dropdown/dropdown.css +1 -1
- package/src/components/dropdown/dropdown.js +5 -3
- package/src/components/empty-state/empty-state.css +2 -2
- package/src/components/entity-ref/entity-ref.css +1 -1
- package/src/components/entity-ref/entity-ref.js +1 -1
- package/src/components/field/field.css +28 -9
- package/src/components/field/field.js +68 -26
- package/src/components/field-upload/field-upload.css +1 -1
- package/src/components/fieldset/fieldset.css +5 -3
- package/src/components/fieldset/fieldset.js +28 -5
- package/src/components/file-item/file-item.js +144 -10
- package/src/components/filter/filter.js +7 -3
- package/src/components/filter-panel/filter-panel.css +1 -1
- package/src/components/finder/finder.css +15 -13
- package/src/components/form/form.css +5 -4
- package/src/components/form/form.js +11 -2
- package/src/components/grid/grid.css +1 -1
- package/src/components/groupbox/groupbox.css +1 -1
- package/src/components/kanban-view/kanban-card.js +11 -3
- package/src/components/kanban-view/kanban-view.css +39 -15
- package/src/components/kanban-view/kanban-view.js +4 -4
- package/src/components/launcher/launcher.css +107 -25
- package/src/components/launcher/launcher.js +503 -41
- package/src/components/list-toolbar/list-toolbar.css +13 -8
- package/src/components/list-toolbar/list-toolbar.js +1 -1
- package/src/components/master-panel/master-panel.css +2 -0
- package/src/components/menu-button/menu-button.css +9 -4
- package/src/components/menu-button/menu-button.js +65 -9
- package/src/components/message/message.css +33 -3
- package/src/components/message/message.js +217 -15
- package/src/components/modal/modal.js +18 -3
- package/src/components/navigation-bar/navigation-bar.css +18 -9
- package/src/components/number-field/field-adapter.js +1 -0
- package/src/components/number-field/number-field.css +70 -0
- package/src/components/number-field/number-field.js +2 -0
- package/src/components/pagination/pagination.css +8 -6
- package/src/components/panel/panel.css +1 -1
- package/src/components/rating/rating.css +7 -0
- package/src/components/select/color.js +22 -0
- package/src/components/select/field-adapter.js +2 -0
- package/src/components/select/glyphs.js +165 -0
- package/src/components/select/select.css +138 -45
- package/src/components/select/select.js +83 -47
- package/src/components/sheet/sheet.css +11 -8
- package/src/components/slider/slider.css +16 -2
- package/src/components/slider/slider.js +1 -1
- package/src/components/sort-control/sort-control.css +4 -1
- package/src/components/stat-tile/stat-tile.css +41 -46
- package/src/components/stat-tile/stat-tile.js +17 -6
- package/src/components/tabbox/tabbox.css +32 -27
- package/src/components/tabbox/tabbox.js +5 -1
- package/src/components/table/table.css +104 -29
- package/src/components/table/table.js +90 -16
- package/src/components/tag-picker/tag-picker.css +83 -5
- package/src/components/tag-picker/tag-picker.js +25 -8
- package/src/components/timebox/timebox.css +22 -2
- package/src/components/toggle/toggle.css +12 -1
- package/src/components/toolbar/toolbar.js +2 -2
- package/src/components/tooltip/tooltip.css +4 -0
- package/src/components/tooltip/tooltip.js +10 -3
- package/src/components/tree/tree.css +25 -16
- package/src/components/tree/tree.js +31 -0
- package/src/components/value-list/value-list.css +3 -3
- package/src/components/view/record-view.js +1 -1
- package/src/core/breakpoint.js +1 -1
- package/src/core/icons.js +193 -60
- package/src/core/motion.js +147 -0
- package/src/core/overlay-host.js +21 -2
- package/src/index.js +5 -3
- package/src/internal/app-rail.js +1 -2
- package/src/zeyos/connect.js +6 -2
- package/src/zeyos/form.js +67 -27
- package/src/zeyos/index.js +1 -1
- package/src/zeyos/query.js +153 -0
- package/src/zeyos/schema.js +144 -27
- package/src/zeyos/table.js +68 -5
- package/src/zeyos/view.js +6 -0
- package/styles/base.css +56 -0
- package/styles/icons.css +11 -1
- package/styles/tokens/dark.css +113 -37
- package/styles/tokens/global.css +121 -27
- package/styles/tokens/semantic.css +100 -31
- package/styles/tokens/themes.css +7 -6
- package/styles/zx.css +0 -1
- package/styles/tokens/density.css +0 -9
package/src/core/icons.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* The icon layer. Two renderers sit behind one `icon()` call:
|
|
4
4
|
*
|
|
5
|
-
* - **built-in** (default) — the inline SVG glyphs below, no network, no
|
|
5
|
+
* - **built-in** (default) — the inline SVG outline glyphs below (Lucide), no network, no
|
|
6
|
+
* stylesheet, no font. Applications can add their own, filled or outlined, with `registerIcons()`.
|
|
6
7
|
* - **Font Awesome** — `<i>` elements carrying Font Awesome classes, after an application opts in
|
|
7
8
|
* with `useFontAwesome()` or `loadFontAwesome(kit)`. Zx never loads a kit by itself.
|
|
8
9
|
*
|
|
@@ -28,52 +29,139 @@ const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
|
28
29
|
*/
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
* How a glyph's path is painted. `'fill'` fills the shape — the form Font Awesome and other solid
|
|
33
|
+
* sets ship in. `'stroke'` draws the outline with the icon pen: `currentColor`, round caps and
|
|
34
|
+
* joins, and a width of 1.75 units in a 24-unit view box — the form the bundled set uses.
|
|
35
|
+
* @typedef {'fill'|'stroke'} IconPaint
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* One inline SVG glyph: `[viewBox, path]` for a filled shape, or `[viewBox, path, 'stroke']` for
|
|
40
|
+
* an outline. A path may hold any number of subpaths; the two-element form is the original format
|
|
41
|
+
* and always renders filled.
|
|
42
|
+
* @typedef {[string, string] | [string, string, IconPaint]} IconGlyph
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/** The view box every bundled glyph is drawn in: Lucide's 24-unit square. */
|
|
46
|
+
const VIEW_BOX = '0 0 24 24';
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Stroke width of an outline glyph, in units of a 24-unit view box. At the default 16px it draws
|
|
50
|
+
* a line of about 1.2px — the stem weight of 13–14px interface text, so an icon sits beside a
|
|
51
|
+
* label without outweighing it.
|
|
52
|
+
*/
|
|
53
|
+
const STROKE_WIDTH = 1.75;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Thinnest line an outline glyph is drawn with, in CSS pixels. Below 16px the proportional width
|
|
57
|
+
* would fall under a pixel and wash out (a 12px chevron, an 8px tick), so small glyphs keep one
|
|
58
|
+
* full pixel instead.
|
|
59
|
+
*/
|
|
60
|
+
const MIN_STROKE_PX = 1;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Wraps bundled path data as an outline glyph in the shared view box.
|
|
64
|
+
* @param {string} path Path data.
|
|
65
|
+
* @returns {IconGlyph}
|
|
66
|
+
*/
|
|
67
|
+
const outline = (path) => [VIEW_BOX, path, 'stroke'];
|
|
68
|
+
|
|
69
|
+
/*
|
|
70
|
+
* @license Lucide 1.53.0 (ISC), including icons derived from Feather (MIT) — notices below.
|
|
71
|
+
*
|
|
72
|
+
* The bundled glyphs are Lucide 1.53.0 (https://lucide.dev), outline icons drawn on a 24-unit grid.
|
|
73
|
+
* Each Lucide icon is stored as one path: its circles, rectangles, lines, and polylines are
|
|
74
|
+
* rewritten as equivalent path data, which renders identically because every part shares the same
|
|
75
|
+
* stroke. Where a Zx name differs from the Lucide one, the Lucide name is noted beside the glyph.
|
|
76
|
+
*
|
|
77
|
+
* ISC License
|
|
78
|
+
*
|
|
79
|
+
* Copyright (c) 2026 Lucide Icons and Contributors
|
|
80
|
+
*
|
|
81
|
+
* Permission to use, copy, modify, and/or distribute this software for any
|
|
82
|
+
* purpose with or without fee is hereby granted, provided that the above
|
|
83
|
+
* copyright notice and this permission notice appear in all copies.
|
|
84
|
+
*
|
|
85
|
+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
86
|
+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
87
|
+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
88
|
+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
89
|
+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
90
|
+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
91
|
+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
92
|
+
*
|
|
93
|
+
* Lucide icons derived from the Feather project (Lucide's LICENSE lists them) are also covered by:
|
|
94
|
+
*
|
|
95
|
+
* The MIT License (MIT)
|
|
96
|
+
*
|
|
97
|
+
* Copyright (c) 2013-present Cole Bemis
|
|
98
|
+
*
|
|
99
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
100
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
101
|
+
* in the Software without restriction, including without limitation the rights
|
|
102
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
103
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
104
|
+
* furnished to do so, subject to the following conditions:
|
|
105
|
+
*
|
|
106
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
107
|
+
* copies or substantial portions of the Software.
|
|
108
|
+
*
|
|
109
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
110
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
111
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
112
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
113
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
114
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
115
|
+
* SOFTWARE.
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The bundled glyph set: outline icons from Lucide (ISC; see the notice above), embedded as path
|
|
120
|
+
* data so the library carries no webfont, stylesheet, or package dependency. Every entry is
|
|
121
|
+
* `[viewBox, path, 'stroke']` in a 24-unit view box. Extend the set with `registerIcons()`; read
|
|
122
|
+
* every available name with `iconNames()`.
|
|
123
|
+
* @type {Readonly<Record<string, IconGlyph>>}
|
|
38
124
|
*/
|
|
39
125
|
export const icons = Object.freeze({
|
|
40
|
-
|
|
41
|
-
'arrow-
|
|
42
|
-
'
|
|
43
|
-
'chevron-
|
|
44
|
-
'chevron-
|
|
45
|
-
'chevron-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
126
|
+
// <lucide-glyphs>
|
|
127
|
+
'arrow-up-wide-short': outline('M3 8l4-4 4 4M7 4v16M11 12h10M11 16h7M11 20h4'), // arrow-up-wide-narrow
|
|
128
|
+
'arrow-down-wide-short': outline('M3 16l4 4 4-4M7 20V4M11 4h10M11 8h7M11 12h4'), // arrow-down-wide-narrow
|
|
129
|
+
'chevron-down': outline('M6 9l6 6 6-6'),
|
|
130
|
+
'chevron-up': outline('M18 15l-6-6-6 6'),
|
|
131
|
+
'chevron-left': outline('M15 18l-6-6 6-6'),
|
|
132
|
+
'chevron-right': outline('M9 18l6-6-6-6'),
|
|
133
|
+
check: outline('M20 6 9 17l-5-5'),
|
|
134
|
+
x: outline('M18 6 6 18M6 6l12 12'),
|
|
135
|
+
plus: outline('M5 12h14M12 5v14'),
|
|
136
|
+
minus: outline('M5 12h14'),
|
|
137
|
+
search: outline('M21 21l-4.34-4.34M3 11a8 8 0 1 0 16 0a8 8 0 1 0-16 0z'),
|
|
138
|
+
calendar: outline('M8 2v3M16 2v3M5 3h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-14a2 2 0 0 1-2-2v-14a2 2 0 0 1 2-2zM3 9h18'),
|
|
139
|
+
clock: outline('M2 12a10 10 0 1 0 20 0a10 10 0 1 0-20 0zM12 6v6l4 2'),
|
|
140
|
+
trash: outline('M10 11v6M14 11v6M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2'),
|
|
141
|
+
gear: outline('M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915M9 12a3 3 0 1 0 6 0a3 3 0 1 0-6 0z'), // settings
|
|
142
|
+
eye: outline('M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0M9 12a3 3 0 1 0 6 0a3 3 0 1 0-6 0z'),
|
|
143
|
+
lock: outline('M5 11h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-14a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2zM7 11V7a5 5 0 0 1 10 0v4'),
|
|
144
|
+
reload: outline('M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8M21 3v5h-5'), // rotate-cw
|
|
145
|
+
list: outline('M3 5h.01M3 12h.01M3 19h.01M8 5h13M8 12h13M8 19h13'),
|
|
146
|
+
filter: outline('M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z'), // funnel
|
|
147
|
+
dots: outline('M11 12a1 1 0 1 0 2 0a1 1 0 1 0-2 0zM18 12a1 1 0 1 0 2 0a1 1 0 1 0-2 0zM4 12a1 1 0 1 0 2 0a1 1 0 1 0-2 0z'), // ellipsis
|
|
148
|
+
info: outline('M2 12a10 10 0 1 0 20 0a10 10 0 1 0-20 0zM12 16v-4M12 8h.01'),
|
|
149
|
+
warning: outline('M21.73 18l-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3M12 9v4M12 17h.01'), // triangle-alert
|
|
150
|
+
error: outline('M2 12a10 10 0 1 0 20 0a10 10 0 1 0-20 0zM12 8V12M12 16H12.01'), // circle-alert
|
|
151
|
+
success: outline('M2 12a10 10 0 1 0 20 0a10 10 0 1 0-20 0zM16 9l-5.5 5.5L8 12'), // circle-check
|
|
152
|
+
upload: outline('M12 3v12M17 8l-5-5-5 5M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'),
|
|
153
|
+
drag: outline('M8 12a1 1 0 1 0 2 0a1 1 0 1 0-2 0zM8 5a1 1 0 1 0 2 0a1 1 0 1 0-2 0zM8 19a1 1 0 1 0 2 0a1 1 0 1 0-2 0zM14 12a1 1 0 1 0 2 0a1 1 0 1 0-2 0zM14 5a1 1 0 1 0 2 0a1 1 0 1 0-2 0zM14 19a1 1 0 1 0 2 0a1 1 0 1 0-2 0z'), // grip-vertical
|
|
154
|
+
star: outline('M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z'),
|
|
155
|
+
heart: outline('M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5'),
|
|
156
|
+
tag: outline('M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42zM7 7.5a.5 .5 0 1 0 1 0a.5 .5 0 1 0-1 0z'),
|
|
157
|
+
folder: outline('M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z'),
|
|
158
|
+
'folder-open': outline('M6 14l1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2'),
|
|
159
|
+
file: outline('M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2zM14 2v5a1 1 0 0 0 1 1h5'),
|
|
160
|
+
copy: outline('M10 8h10a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-10a2 2 0 0 1-2-2v-10a2 2 0 0 1 2-2zM4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2'),
|
|
161
|
+
square: outline('M5 3h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-14a2 2 0 0 1-2-2v-14a2 2 0 0 1 2-2z'),
|
|
162
|
+
code: outline('M18 16l4-4-4-4M6 8l-4 4 4 4M14.5 4l-5 16'), // code-xml
|
|
163
|
+
book: outline('M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20')
|
|
164
|
+
// </lucide-glyphs>
|
|
77
165
|
});
|
|
78
166
|
|
|
79
167
|
/** Legacy gx Factory icon names mapped to their Zx equivalents. */
|
|
@@ -86,7 +174,7 @@ const aliases = Object.freeze({
|
|
|
86
174
|
fields: 'list'
|
|
87
175
|
});
|
|
88
176
|
|
|
89
|
-
/** @type {Record<string,
|
|
177
|
+
/** @type {Record<string, IconGlyph>} Glyphs added at runtime by `registerIcons`. */
|
|
90
178
|
const extraGlyphs = Object.create(null);
|
|
91
179
|
|
|
92
180
|
/**
|
|
@@ -163,17 +251,31 @@ export async function loadFontAwesome(options) {
|
|
|
163
251
|
}
|
|
164
252
|
|
|
165
253
|
/**
|
|
166
|
-
* Adds inline SVG glyphs to the built-in set, or replaces existing ones.
|
|
167
|
-
*
|
|
168
|
-
*
|
|
254
|
+
* Adds inline SVG glyphs to the built-in set, or replaces existing ones.
|
|
255
|
+
*
|
|
256
|
+
* An entry is `[viewBox, path]` — a filled shape, the format Font Awesome path data comes in, and
|
|
257
|
+
* how it always rendered — or `[viewBox, path, 'stroke']` — an outline drawn with the same pen as
|
|
258
|
+
* the bundled set: `currentColor`, round caps and joins, and a stroke scaled to the view box, so a
|
|
259
|
+
* glyph from a 24-unit outline set such as Lucide renders exactly like a bundled one.
|
|
260
|
+
*
|
|
261
|
+
* registerIcons({ rocket: ['0 0 512 512', 'M…'] }); // filled
|
|
262
|
+
* registerIcons({ anchor: ['0 0 24 24', 'M12 6v16…', 'stroke'] }); // outline
|
|
263
|
+
* @param {Record<string, IconGlyph>} glyphs Glyphs keyed by icon name.
|
|
169
264
|
* @returns {void}
|
|
265
|
+
* @throws {TypeError} When an entry is neither a `[viewBox, path]` pair nor a
|
|
266
|
+
* `[viewBox, path, 'fill'|'stroke']` triple.
|
|
170
267
|
*/
|
|
171
268
|
export function registerIcons(glyphs) {
|
|
172
269
|
for (const [name, entry] of Object.entries(glyphs)) {
|
|
173
|
-
if (!Array.isArray(entry) || entry.length !== 2)
|
|
174
|
-
|
|
270
|
+
if (!Array.isArray(entry) || (entry.length !== 2 && entry.length !== 3)
|
|
271
|
+
|| (entry.length === 3 && entry[2] !== 'fill' && entry[2] !== 'stroke')) {
|
|
272
|
+
throw new TypeError(
|
|
273
|
+
`Icon "${name}" must be a [viewBox, path] pair or a [viewBox, path, 'stroke'] triple`
|
|
274
|
+
);
|
|
175
275
|
}
|
|
176
|
-
extraGlyphs[name] =
|
|
276
|
+
extraGlyphs[name] = entry[2] === 'stroke'
|
|
277
|
+
? [String(entry[0]), String(entry[1]), 'stroke']
|
|
278
|
+
: [String(entry[0]), String(entry[1])];
|
|
177
279
|
}
|
|
178
280
|
}
|
|
179
281
|
|
|
@@ -244,8 +346,8 @@ function builtinIcon(name, options) {
|
|
|
244
346
|
warnMissingIcon(name);
|
|
245
347
|
return missingIcon(name, options);
|
|
246
348
|
}
|
|
247
|
-
const [viewBox, pathData] = entry;
|
|
248
|
-
const svg = iconSvg(viewBox, options);
|
|
349
|
+
const [viewBox, pathData, paint = 'fill'] = entry;
|
|
350
|
+
const svg = iconSvg(viewBox, paint, options);
|
|
249
351
|
const path = document.createElementNS(SVG_NS, 'path');
|
|
250
352
|
path.setAttribute('d', pathData);
|
|
251
353
|
svg.append(path);
|
|
@@ -254,26 +356,57 @@ function builtinIcon(name, options) {
|
|
|
254
356
|
|
|
255
357
|
/**
|
|
256
358
|
* Builds the `<svg>` root every inline glyph shares, so the placeholder is the same element in
|
|
257
|
-
* the same box as the icon it stands in for.
|
|
359
|
+
* the same box as the icon it stands in for. The paint attributes sit on the root and the path
|
|
360
|
+
* inherits them, so component CSS can restyle a glyph with `fill`, `stroke`, or `color` on the
|
|
361
|
+
* `.zx-icon` element alone — `fill: currentColor` turns an outline into its solid form, for a set
|
|
362
|
+
* star or a liked heart.
|
|
258
363
|
* @param {string} viewBox The glyph's view box.
|
|
364
|
+
* @param {IconPaint} paint Whether the glyph is filled or stroked.
|
|
259
365
|
* @param {IconOptions} options Display and accessibility options.
|
|
260
366
|
* @returns {SVGSVGElement}
|
|
261
367
|
*/
|
|
262
|
-
function iconSvg(viewBox, options) {
|
|
368
|
+
function iconSvg(viewBox, paint, options) {
|
|
263
369
|
const { size = 16 } = options;
|
|
264
370
|
const svg = document.createElementNS(SVG_NS, 'svg');
|
|
265
371
|
svg.setAttribute('class', classList('zx-icon', options.class));
|
|
266
372
|
svg.setAttribute('viewBox', viewBox);
|
|
267
373
|
svg.setAttribute('width', String(size));
|
|
268
374
|
svg.setAttribute('height', String(size));
|
|
269
|
-
|
|
375
|
+
if (paint === 'stroke') {
|
|
376
|
+
svg.setAttribute('fill', 'none');
|
|
377
|
+
svg.setAttribute('stroke', 'currentColor');
|
|
378
|
+
svg.setAttribute('stroke-width', strokeWidth(viewBox, size));
|
|
379
|
+
svg.setAttribute('stroke-linecap', 'round');
|
|
380
|
+
svg.setAttribute('stroke-linejoin', 'round');
|
|
381
|
+
} else {
|
|
382
|
+
svg.setAttribute('fill', 'currentColor');
|
|
383
|
+
}
|
|
270
384
|
svg.setAttribute('focusable', 'false');
|
|
271
385
|
applyLabel(svg, options.label ?? null);
|
|
272
386
|
return svg;
|
|
273
387
|
}
|
|
274
388
|
|
|
275
|
-
/**
|
|
276
|
-
|
|
389
|
+
/**
|
|
390
|
+
* The stroke width an outline glyph is drawn with, in its own view-box units: `STROKE_WIDTH` per
|
|
391
|
+
* 24 units, so outline sets drawn on another grid keep the same weight, and never thinner than
|
|
392
|
+
* `MIN_STROKE_PX` at the rendered size. A size given as a CSS length other than pixels (`'1em'`)
|
|
393
|
+
* cannot be measured here and keeps the proportional width.
|
|
394
|
+
* @param {string} viewBox The glyph's view box.
|
|
395
|
+
* @param {number|string} size The rendered size the caller asked for.
|
|
396
|
+
* @returns {string}
|
|
397
|
+
*/
|
|
398
|
+
function strokeWidth(viewBox, size) {
|
|
399
|
+
const [, , width, height] = viewBox.trim().split(/[\s,]+/).map(Number);
|
|
400
|
+
const extent = Math.max(width, height) || 24;
|
|
401
|
+
let units = STROKE_WIDTH * extent / 24;
|
|
402
|
+
const pixels = typeof size === 'number' ? size
|
|
403
|
+
: /^\d*\.?\d+(px)?$/.test(String(size).trim()) ? parseFloat(String(size)) : NaN;
|
|
404
|
+
if (pixels > 0) units = Math.max(units, MIN_STROKE_PX * extent / pixels);
|
|
405
|
+
return String(Math.round(units * 1000) / 1000);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/** View box the placeholder reserves — the square the bundled glyphs are drawn in. */
|
|
409
|
+
const PLACEHOLDER_VIEW_BOX = VIEW_BOX;
|
|
277
410
|
|
|
278
411
|
/**
|
|
279
412
|
* The element an unresolvable name renders as: the ordinary `zx-icon` root at the requested size,
|
|
@@ -290,7 +423,7 @@ const PLACEHOLDER_VIEW_BOX = '0 0 512 512';
|
|
|
290
423
|
* @returns {SVGSVGElement}
|
|
291
424
|
*/
|
|
292
425
|
function missingIcon(name, options) {
|
|
293
|
-
const svg = iconSvg(PLACEHOLDER_VIEW_BOX, options);
|
|
426
|
+
const svg = iconSvg(PLACEHOLDER_VIEW_BOX, 'stroke', options);
|
|
294
427
|
svg.setAttribute('data-zx-icon-missing', name);
|
|
295
428
|
return svg;
|
|
296
429
|
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/**
|
|
3
|
+
* Motion as a setting, for the code that animates in script.
|
|
4
|
+
*
|
|
5
|
+
* CSS motion needs nothing from here: `tokens/global.css` sets every `--zx-dur-*` to 0ms and
|
|
6
|
+
* `base.css` stops animations and transitions both under the operating system's reduced-motion
|
|
7
|
+
* preference and inside any `data-zx-motion="reduced"` region. A chart engine's own tweening, a
|
|
8
|
+
* `requestAnimationFrame` loop, or `element.animate()` never sees those rules, so a component that
|
|
9
|
+
* moves things itself asks `prefersReducedMotion()` before it starts and `watchMotion()` for the
|
|
10
|
+
* moment the answer changes.
|
|
11
|
+
*
|
|
12
|
+
* There is no "full motion" value: a region can only ask for less. Someone who asked their system
|
|
13
|
+
* for reduced motion gets it whatever an application or a region says.
|
|
14
|
+
* @module zx/core/motion
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** The attribute that marks a reduced-motion region. Its one meaningful value is `reduced`. */
|
|
18
|
+
export const MOTION_ATTRIBUTE = 'data-zx-motion';
|
|
19
|
+
|
|
20
|
+
const REDUCED_REGION = '[data-zx-motion="reduced"]';
|
|
21
|
+
const REDUCED_QUERY = '(prefers-reduced-motion: reduce)';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Whether motion should stop where `element` is: true under the operating system's reduced-motion
|
|
25
|
+
* preference, or when the element sits inside a `data-zx-motion="reduced"` region (the element
|
|
26
|
+
* itself included). The region check crosses shadow-root boundaries.
|
|
27
|
+
* @param {Element|null} [element] Where the motion would happen. Omitted, the document root is
|
|
28
|
+
* asked — which answers for an application that sets the attribute on `<html>`.
|
|
29
|
+
* @returns {boolean}
|
|
30
|
+
*/
|
|
31
|
+
export function prefersReducedMotion(element) {
|
|
32
|
+
if (systemPrefersReducedMotion()) return true;
|
|
33
|
+
const target = element ?? globalThis.document?.documentElement ?? null;
|
|
34
|
+
return inReducedRegion(target);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @typedef {Object} WatchMotionOptions
|
|
39
|
+
* @property {AbortSignal} [signal] Stops watching when aborted, exactly as calling the returned
|
|
40
|
+
* disposer does. A signal that is already aborted watches nothing.
|
|
41
|
+
* @property {boolean} [immediate=false] Also calls back once, synchronously, with the current
|
|
42
|
+
* answer — convenient for a loop that starts or stays stopped in the same callback.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Calls back whenever `prefersReducedMotion(element)` changes: when the operating-system preference
|
|
47
|
+
* flips, or when a `data-zx-motion` attribute is set, changed, or removed on the element or any
|
|
48
|
+
* ancestor (in the document, or in the shadow root the element lives in). The callback receives
|
|
49
|
+
* the new answer and runs only on a real change.
|
|
50
|
+
*
|
|
51
|
+
* Moving the element into or out of a reduced region is not observed — ask
|
|
52
|
+
* `prefersReducedMotion()` again after re-parenting.
|
|
53
|
+
* @param {Element|null} element Where the motion happens. Null watches the document root.
|
|
54
|
+
* @param {(reduced: boolean) => void} fn Receives `true` when motion must stop, `false` when it may
|
|
55
|
+
* run again.
|
|
56
|
+
* @param {WatchMotionOptions} [options={}]
|
|
57
|
+
* @returns {() => void} Disposer: stops watching. Safe to call more than once.
|
|
58
|
+
*/
|
|
59
|
+
export function watchMotion(element, fn, options = {}) {
|
|
60
|
+
if (typeof fn !== 'function') throw new TypeError('watchMotion requires a callback');
|
|
61
|
+
const { signal, immediate = false } = options;
|
|
62
|
+
if (signal?.aborted) return () => {};
|
|
63
|
+
|
|
64
|
+
let current = prefersReducedMotion(element);
|
|
65
|
+
let stopped = false;
|
|
66
|
+
|
|
67
|
+
const check = () => {
|
|
68
|
+
if (stopped) return;
|
|
69
|
+
const next = prefersReducedMotion(element);
|
|
70
|
+
if (next === current) return;
|
|
71
|
+
current = next;
|
|
72
|
+
fn(next);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const media = typeof globalThis.matchMedia === 'function' ? globalThis.matchMedia(REDUCED_QUERY) : null;
|
|
76
|
+
media?.addEventListener?.('change', check);
|
|
77
|
+
|
|
78
|
+
// One observer over every tree the element's ancestry passes through: the document, and each
|
|
79
|
+
// shadow root on the way up. The attribute filter keeps it to the one attribute that matters.
|
|
80
|
+
const observer = typeof MutationObserver === 'function' ? new MutationObserver(check) : null;
|
|
81
|
+
if (observer) {
|
|
82
|
+
for (const root of treesAbove(element)) {
|
|
83
|
+
observer.observe(root, { attributes: true, attributeFilter: [MOTION_ATTRIBUTE], subtree: true });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const stop = () => {
|
|
88
|
+
if (stopped) return;
|
|
89
|
+
stopped = true;
|
|
90
|
+
media?.removeEventListener?.('change', check);
|
|
91
|
+
observer?.disconnect();
|
|
92
|
+
signal?.removeEventListener('abort', stop);
|
|
93
|
+
};
|
|
94
|
+
signal?.addEventListener('abort', stop, { once: true });
|
|
95
|
+
|
|
96
|
+
if (immediate) fn(current);
|
|
97
|
+
return stop;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** @returns {boolean} Whether the operating system asks for reduced motion. */
|
|
101
|
+
function systemPrefersReducedMotion() {
|
|
102
|
+
return typeof globalThis.matchMedia === 'function' && globalThis.matchMedia(REDUCED_QUERY).matches;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* @param {Element|null} element
|
|
107
|
+
* @returns {boolean} Whether the element is inside a reduced region, across shadow boundaries.
|
|
108
|
+
*/
|
|
109
|
+
function inReducedRegion(element) {
|
|
110
|
+
/** @type {Element|null} */
|
|
111
|
+
let node = element;
|
|
112
|
+
while (node && typeof node.closest === 'function') {
|
|
113
|
+
if (node.closest(REDUCED_REGION)) return true;
|
|
114
|
+
const root = node.getRootNode?.();
|
|
115
|
+
node = isShadowRoot(root) ? root.host : null;
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The trees a region attribute could be set in: the shadow roots on the element's way up, and the
|
|
122
|
+
* document element.
|
|
123
|
+
* @param {Element|null} element
|
|
124
|
+
* @returns {Node[]}
|
|
125
|
+
*/
|
|
126
|
+
function treesAbove(element) {
|
|
127
|
+
const trees = [];
|
|
128
|
+
/** @type {Element|null} */
|
|
129
|
+
let node = element;
|
|
130
|
+
while (node && typeof node.getRootNode === 'function') {
|
|
131
|
+
const root = node.getRootNode();
|
|
132
|
+
if (!isShadowRoot(root)) break;
|
|
133
|
+
trees.push(root);
|
|
134
|
+
node = root.host;
|
|
135
|
+
}
|
|
136
|
+
const documentElement = (element?.ownerDocument ?? globalThis.document)?.documentElement;
|
|
137
|
+
if (documentElement) trees.push(documentElement);
|
|
138
|
+
return trees;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @param {unknown} node
|
|
143
|
+
* @returns {node is ShadowRoot}
|
|
144
|
+
*/
|
|
145
|
+
function isShadowRoot(node) {
|
|
146
|
+
return Boolean(node) && /** @type {Node} */ (node).nodeType === 11 && 'host' in /** @type {object} */ (node);
|
|
147
|
+
}
|
package/src/core/overlay-host.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { resolveElement } from './dom.js';
|
|
2
2
|
|
|
3
|
-
const SCOPE_SELECTOR = '.zx-scope, [data-zx-theme], [data-zx-
|
|
3
|
+
const SCOPE_SELECTOR = '.zx-scope, [data-zx-theme], [data-zx-preset]';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Finds the closest styling scope for a top-layer element.
|
|
7
7
|
*
|
|
8
8
|
* Popovers and dialogs escape clipping even when their DOM parent is inside an application shell,
|
|
9
|
-
* so keeping them below that parent preserves inherited theme,
|
|
9
|
+
* so keeping them below that parent preserves inherited theme, preset, material, and product
|
|
10
10
|
* token overrides without sacrificing top-layer behaviour. The document body remains the safe
|
|
11
11
|
* fallback for unscoped applications.
|
|
12
12
|
*
|
|
@@ -21,3 +21,22 @@ export function overlayHost(source = null) {
|
|
|
21
21
|
if (!scope || scope === document.documentElement || scope === document.body) return document.body;
|
|
22
22
|
return scope;
|
|
23
23
|
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Like `overlayHost()`, but declines to guess for a source that is not in the document yet.
|
|
27
|
+
*
|
|
28
|
+
* A component created before its anchor is connected cannot know which themed region the anchor
|
|
29
|
+
* will end up in: the anchor's ancestors are not there yet, so `overlayHost()` would answer
|
|
30
|
+
* `<body>`, outside every `[data-zx-theme]` and `.zx-scope`. This returns null instead, so the
|
|
31
|
+
* overlay can stay detached until it first opens and resolve its host with `overlayHost()` then,
|
|
32
|
+
* when the anchor is in place. The focused-element default (`source` null) is always connected and
|
|
33
|
+
* resolves exactly as `overlayHost()` does.
|
|
34
|
+
*
|
|
35
|
+
* @param {Element|string|null} [source=null] Element or selector whose styling scope should own the overlay.
|
|
36
|
+
* @returns {Element|null} The host, or null while the source is not connected to the document.
|
|
37
|
+
*/
|
|
38
|
+
export function connectedOverlayHost(source = null) {
|
|
39
|
+
if (source == null) return overlayHost(null);
|
|
40
|
+
const context = resolveElement(source);
|
|
41
|
+
return context?.isConnected ? overlayHost(context) : null;
|
|
42
|
+
}
|
package/src/index.js
CHANGED
|
@@ -52,6 +52,7 @@ export {
|
|
|
52
52
|
} from './core/dom.js';
|
|
53
53
|
export { position } from './core/position.js';
|
|
54
54
|
export { breakpoints, breakpointOf, matchBreakpoint, onBreakpoint } from './core/breakpoint.js';
|
|
55
|
+
export { MOTION_ATTRIBUTE, prefersReducedMotion, watchMotion } from './core/motion.js';
|
|
55
56
|
export { Http, zeyosService, parseResult } from './core/http.js';
|
|
56
57
|
export { setTranslator, setLanguage, getLanguage, translate, printf } from './core/i18n.js';
|
|
57
58
|
export { focusTrap, rovingTabindex, typeahead } from './core/keyboard.js';
|
|
@@ -75,8 +76,8 @@ export {
|
|
|
75
76
|
export { storage } from './core/storage.js';
|
|
76
77
|
export { toCsv, downloadBlob, copyToClipboard } from './core/export.js';
|
|
77
78
|
export { defineElements } from './elements/define.js';
|
|
78
|
-
export { button, buttonGroup } from './components/button/button.js';
|
|
79
|
-
export { badge, badgeGroup } from './components/badge/badge.js';
|
|
79
|
+
export { button, buttonGroup, setButtonBusy } from './components/button/button.js';
|
|
80
|
+
export { BADGE_TONES, badge, badgeGroup } from './components/badge/badge.js';
|
|
80
81
|
export { CheckButton } from './components/check-button/check-button.js';
|
|
81
82
|
export { emptyState } from './components/empty-state/empty-state.js';
|
|
82
83
|
export { spinner } from './components/loading/spinner.js';
|
|
@@ -108,7 +109,7 @@ export { Pagination, paginationRange } from './components/pagination/pagination.
|
|
|
108
109
|
export { Search } from './components/search/search.js';
|
|
109
110
|
export { AppIcon, appIcon } from './components/app-icon/app-icon.js';
|
|
110
111
|
export { Launcher, rankLauncherItems } from './components/launcher/launcher.js';
|
|
111
|
-
export { Avatar, avatarInitials } from './components/avatar/avatar.js';
|
|
112
|
+
export { AVATAR_TONES, Avatar, avatarInitials, avatarTone } from './components/avatar/avatar.js';
|
|
112
113
|
export {
|
|
113
114
|
EntityRef, normalizeEntityRef, normalizeEntityRefLink,
|
|
114
115
|
normalizeEntityRefMetadata, normalizeEntityRefActions
|
|
@@ -134,6 +135,7 @@ export { Tooltip, tooltip, describe } from './components/tooltip/tooltip.js';
|
|
|
134
135
|
export { MenuButton } from './components/menu-button/menu-button.js';
|
|
135
136
|
export { ContextMenu } from './components/context-menu/context-menu.js';
|
|
136
137
|
export { Select } from './components/select/select.js';
|
|
138
|
+
export { statusIcon, priorityIcon } from './components/select/glyphs.js';
|
|
137
139
|
export { Checklist } from './components/checklist/checklist.js';
|
|
138
140
|
export { TagPicker } from './components/tag-picker/tag-picker.js';
|
|
139
141
|
export { NumberField, parseNumber, snapNumber } from './components/number-field/number-field.js';
|
package/src/internal/app-rail.js
CHANGED
|
@@ -294,8 +294,7 @@ export class AppRailPresenter extends Component {
|
|
|
294
294
|
const actualPanel = dropdown.getPanel();
|
|
295
295
|
actualPanel.classList.add('zx-app-rail__popover');
|
|
296
296
|
// The panel is portaled out of the rail, so its stylesheet cannot ask which edge the rail
|
|
297
|
-
// occupies. Presentation only: it
|
|
298
|
-
// on a right-hand rail, exactly as the expanded tree does.
|
|
297
|
+
// occupies. Presentation only: it tells the panel's styles which side it opened from.
|
|
299
298
|
actualPanel.dataset.side = this.el.dataset.side;
|
|
300
299
|
actualPanel.setAttribute('role', 'region');
|
|
301
300
|
actualPanel.setAttribute('aria-label', this._message('appRail.subNavigation', '%1 sub-navigation', item.label));
|
package/src/zeyos/connect.js
CHANGED
|
@@ -107,8 +107,12 @@ function isRecord(value) {
|
|
|
107
107
|
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
/**
|
|
111
|
-
|
|
110
|
+
/**
|
|
111
|
+
* The text a failed request is reported with: the error's own message, or a generic sentence.
|
|
112
|
+
* @param {unknown} error Rejection reason.
|
|
113
|
+
* @returns {string}
|
|
114
|
+
*/
|
|
115
|
+
export function errorMessage(error) {
|
|
112
116
|
if (error instanceof Error && error.message) return error.message;
|
|
113
117
|
if (error && typeof error === 'object' && typeof error.message === 'string') return error.message;
|
|
114
118
|
return String(error ?? 'ZeyOS request failed');
|