vanilla-jui 1.3.11 → 1.4.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 (71) hide show
  1. package/dist/index.d.ts +2927 -0
  2. package/dist/index.js +1 -1
  3. package/dist/index.umd.js +1 -1
  4. package/dist/style.css +1 -1
  5. package/package.json +4 -3
  6. package/src/components/accordion.ts +522 -0
  7. package/src/components/drop.ts +497 -0
  8. package/src/components/flow.ts +1579 -0
  9. package/src/components/form.ts +953 -0
  10. package/src/components/{icons.js → icons.ts} +24 -11
  11. package/src/components/menu.ts +615 -0
  12. package/src/components/{modal.js → modal.ts} +560 -237
  13. package/src/components/offcanvas.ts +496 -0
  14. package/src/components/{pagination.js → pagination.ts} +251 -76
  15. package/src/components/parabola.ts +335 -0
  16. package/src/components/{sticky.js → sticky.ts} +123 -98
  17. package/src/components/{swiper.js → swiper.ts} +510 -232
  18. package/src/components/tabs.ts +984 -0
  19. package/src/components/theme.ts +437 -0
  20. package/src/components/toast.ts +371 -0
  21. package/src/components/toc.ts +385 -0
  22. package/src/components/tooltip.ts +179 -0
  23. package/src/components/validator.ts +596 -0
  24. package/src/core/{Component.js → Component.ts} +134 -27
  25. package/src/css/animation.css +31 -1
  26. package/src/css/card.css +1 -1
  27. package/src/css/color.css +863 -1013
  28. package/src/css/color_p3.css +822 -975
  29. package/src/css/components.css +1 -0
  30. package/src/css/form.css +1 -1
  31. package/src/css/icon.css +17 -1
  32. package/src/css/index.css +2 -2
  33. package/src/css/menu.css +1 -1
  34. package/src/css/tabs.css +1 -0
  35. package/src/css/tokens.css +1 -1
  36. package/src/index.ts +37 -0
  37. package/src/locales/{index.js → index.ts} +1 -2
  38. package/src/types.d.ts +1 -0
  39. package/src/utilities/browser.ts +131 -0
  40. package/src/utilities/cache.ts +57 -0
  41. package/src/utilities/core.ts +614 -0
  42. package/src/utilities/dom.ts +468 -0
  43. package/src/utilities/events.ts +106 -0
  44. package/src/utilities/http.ts +35 -0
  45. package/src/utilities/storage.ts +46 -0
  46. package/src/components/accordion.js +0 -373
  47. package/src/components/drop.js +0 -437
  48. package/src/components/flow.js +0 -1133
  49. package/src/components/form.js +0 -585
  50. package/src/components/menu.js +0 -422
  51. package/src/components/offcanvas.js +0 -332
  52. package/src/components/parabola.js +0 -295
  53. package/src/components/tabs.js +0 -746
  54. package/src/components/theme.js +0 -353
  55. package/src/components/toast.js +0 -329
  56. package/src/components/toc.js +0 -226
  57. package/src/components/tooltip.js +0 -86
  58. package/src/components/validator.js +0 -586
  59. package/src/index.js +0 -45
  60. package/src/locales/index.min.js +0 -1
  61. package/src/utilities/browser.js +0 -111
  62. package/src/utilities/cache.js +0 -159
  63. package/src/utilities/core.js +0 -502
  64. package/src/utilities/debug.js +0 -103
  65. package/src/utilities/dom.js +0 -313
  66. package/src/utilities/events.js +0 -69
  67. package/src/utilities/http.js +0 -30
  68. package/src/utilities/legacy-dom.js +0 -179
  69. package/src/utilities/storage.js +0 -46
  70. /package/src/{components/components.js → css/themes/index.css} +0 -0
  71. /package/src/icons/{index.js → index.ts} +0 -0
@@ -1,226 +0,0 @@
1
- import { createDeepStore } from 'vanilla-signal';
2
-
3
- import Component from '../core/Component.js';
4
- import { randomId, resolveProps } from '../utilities/core.js';
5
- import { requireContainer, requireRenderDOM } from '../utilities/dom.js';
6
-
7
- const TOC_PROPS_SCHEMA = {
8
- container: { default: null },
9
- target: { default: '.j-content' },
10
- headings: { default: 'h2, h3', type: 'string' },
11
- offset: {
12
- default: 80,
13
- type: 'number',
14
- validate: (value) => value >= 0,
15
- message: 'expects a positive number or 0.',
16
- },
17
- onUpdate: { default: null, types: ['function', 'null'] },
18
- };
19
-
20
- function resolveHeadingLevel(element) {
21
- const match = /^H([1-6])$/.exec(element.tagName);
22
- return match ? Number(match[1]) : 1;
23
- }
24
-
25
- function normalizeHeading(element, index) {
26
- if (!element.id) element.id = `toc-${randomId()}-${index}`;
27
- return {
28
- id: element.id,
29
- text: element.textContent || '',
30
- level: resolveHeadingLevel(element),
31
- element,
32
- };
33
- }
34
-
35
- /**
36
- * 页面目录组件。
37
- *
38
- * 扫描内容区域内的标题,生成锚点列表,并随页面滚动更新 active 状态。
39
- */
40
- export class Toc extends Component {
41
- /**
42
- * 创建 Toc 实例。
43
- * @param {object} [input={}] Toc 配置。
44
- */
45
- constructor(input = {}) {
46
- const props = resolveProps(input, TOC_PROPS_SCHEMA, 'Toc.props');
47
- super(props);
48
-
49
- this.dom.container = null;
50
- this.dom.target = null;
51
- this.dom.list = null;
52
- this.dom.headings = [];
53
- this.dom.links = [];
54
-
55
- this.runtime.built = false;
56
- this.runtime.ticking = false;
57
-
58
- this.state = createDeepStore({
59
- items: [],
60
- current: {
61
- index: -1,
62
- item: null,
63
- },
64
- });
65
- }
66
-
67
- /**
68
- * 构建 Toc DOM 和滚动监听。
69
- * @returns {Toc} 当前实例。
70
- */
71
- build() {
72
- if (this.runtime.destroyed)
73
- throw new Error('Toc.build: instance destroyed');
74
- if (this.runtime.built) return this;
75
-
76
- requireRenderDOM('Toc');
77
-
78
- this.init(this.props);
79
- this.dom.container = requireContainer(
80
- this.props.container,
81
- 'Toc.container'
82
- );
83
- this.dom.target = requireContainer(this.props.target, 'Toc.target');
84
- this.root = document.createElement('nav');
85
- this.root.className = 'j-toc';
86
- this.dom.list = document.createElement('div');
87
- this.dom.list.className = 'toc-list';
88
- this.root.appendChild(this.dom.list);
89
- this.dom.container.innerHTML = '';
90
- this.dom.container.appendChild(this.root);
91
-
92
- this.runtime.built = true;
93
- this.refresh();
94
- return this;
95
- }
96
-
97
- _bindEvents() {
98
- this.cleanup.events.on('scroll', window, 'scroll', () => this._onScroll(), {
99
- passive: true,
100
- });
101
- }
102
-
103
- _onScroll() {
104
- if (this.runtime.ticking) return;
105
-
106
- requestAnimationFrame(() => {
107
- this._updateActive();
108
- this.runtime.ticking = false;
109
- });
110
- this.runtime.ticking = true;
111
- }
112
-
113
- _buildLink(item) {
114
- const link = document.createElement('a');
115
- link.href = `#${item.id}`;
116
- link.className = `toc-link is-level-${item.level}`;
117
- link.textContent = item.text;
118
- link.dataset.tocTarget = item.id;
119
-
120
- return link;
121
- }
122
-
123
- _updateActive() {
124
- if (!this.runtime.built) return;
125
-
126
- let index = -1;
127
- for (let i = this.dom.headings.length - 1; i >= 0; i--) {
128
- if (
129
- this.dom.headings[i].getBoundingClientRect().top <= this.props.offset
130
- ) {
131
- index = i;
132
- break;
133
- }
134
- }
135
-
136
- if (index === this.state.current.index) return;
137
-
138
- const current = this.state.items[index] || null;
139
- this.setState({
140
- current: { index, item: current },
141
- });
142
-
143
- this.dom.links.forEach((link, i) => {
144
- const active = i === index;
145
- link.dataset.active = active ? '1' : '0';
146
- link.className = `toc-link is-level-${this.state.items[i].level}${
147
- active ? ' is-active' : ''
148
- }`;
149
- });
150
-
151
- if (typeof this.props.onUpdate === 'function') {
152
- this.props.onUpdate(current, index, this);
153
- }
154
- }
155
-
156
- /**
157
- * 重新扫描标题并重建目录列表。
158
- * @returns {Toc} 当前实例。
159
- */
160
- refresh() {
161
- if (this.runtime.destroyed || !this.runtime.built) return this;
162
-
163
- this.cleanup.events.clear();
164
-
165
- this.dom.headings = Array.from(
166
- this.dom.target.querySelectorAll(this.props.headings)
167
- );
168
- const items = this.dom.headings.map(normalizeHeading);
169
- this.dom.links = items.map((item) => this._buildLink(item));
170
-
171
- this.dom.list.innerHTML = '';
172
- for (const link of this.dom.links) this.dom.list.appendChild(link);
173
-
174
- this.setState({
175
- items,
176
- current: { index: -1, item: null },
177
- });
178
-
179
- this._bindEvents();
180
- this._updateActive();
181
- return this;
182
- }
183
-
184
- /**
185
- * 激活并滚动到指定目录项。
186
- * @param {number} index 目录项索引。
187
- * @returns {Toc} 当前实例。
188
- */
189
- activate(index) {
190
- if (!this.runtime.built) return this;
191
- if (
192
- !Number.isInteger(index) ||
193
- index < 0 ||
194
- index >= this.dom.links.length
195
- ) {
196
- return this;
197
- }
198
-
199
- this.dom.links[index].scrollIntoView({
200
- behavior: 'smooth',
201
- block: 'start',
202
- });
203
- return this;
204
- }
205
-
206
- /**
207
- * 销毁实例并清空渲染内容。
208
- * @private
209
- */
210
- onDestroy() {
211
- this.cleanup.events.clear();
212
- if (this.dom.container) this.dom.container.innerHTML = '';
213
-
214
- this.runtime.built = false;
215
- this.runtime.ticking = false;
216
- this.dom.container = null;
217
- this.dom.target = null;
218
- this.dom.list = null;
219
- this.dom.headings = [];
220
- this.dom.links = [];
221
- }
222
- }
223
-
224
- export function createToc(props = {}) {
225
- return new Toc(props);
226
- }
@@ -1,86 +0,0 @@
1
- import { jsx } from 'vanilla-signal';
2
-
3
- import { resolveProps } from '../utilities/core.js';
4
- import { Drop } from './drop.js';
5
-
6
- const TOOLTIP_OPTIONS_SCHEMA = {
7
- name: { default: null, types: ['string', 'null'] },
8
- mode: { default: 'hover', type: 'string' },
9
- position: { default: 'auto', type: 'string' },
10
- offset: { default: 8, type: 'number' },
11
- message: {
12
- default: '',
13
- type: 'string',
14
- normalize: (value) => String(value || '').trim(),
15
- validate: (value) => value.length > 0,
16
- message: 'expects a non-empty string.',
17
- },
18
- className: { default: null, types: ['string', 'null'] },
19
- id: { default: null, types: ['string', 'null'] },
20
- delay: { default: 100, types: ['number', 'object'] },
21
- hoverIntent: { default: true, type: 'boolean' },
22
- };
23
-
24
- /**
25
- * Tooltip 提示组件。
26
- *
27
- * 基于 Drop 实现,提供更轻量的文本提示封装。
28
- */
29
- export class Tooltip {
30
- /**
31
- * 创建 Tooltip 实例。
32
- * @param {HTMLElement} element 目标元素。
33
- * @param {object} [props={}] 提示配置。
34
- */
35
- constructor(element, props = {}) {
36
- const settings = resolveProps(
37
- props,
38
- TOOLTIP_OPTIONS_SCHEMA,
39
- 'Tooltip.props'
40
- );
41
-
42
- this.drop = new Drop(element, {
43
- ...settings,
44
- content: this._buildContent(settings),
45
- });
46
- }
47
-
48
- /**
49
- * 创建 Tooltip 内容节点。
50
- * @private
51
- */
52
- _buildContent(settings) {
53
- const cls = settings.className
54
- ? `j-tooltip ${settings.className}`
55
- : 'j-tooltip';
56
- return jsx('div', {
57
- className: cls,
58
- children: jsx('div', {
59
- className: 'tooltip-message',
60
- children: settings.message,
61
- }),
62
- });
63
- }
64
-
65
- show(useDelay = true) {
66
- this.drop.show(useDelay);
67
- }
68
-
69
- hide(useDelay = true) {
70
- this.drop.hide(useDelay);
71
- }
72
-
73
- toggle() {
74
- this.drop.toggle();
75
- }
76
-
77
- destroy() {
78
- if (!this.drop) return;
79
- this.drop.destroy();
80
- this.drop = null;
81
- }
82
- }
83
-
84
- export function createTooltip(element, props = {}) {
85
- return new Tooltip(element, props);
86
- }