@hoci/components 0.4.3 → 0.5.1

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/dist/index.mjs CHANGED
@@ -1,6 +1,8 @@
1
- import { defineComponent, h, renderSlot, capitalize } from 'vue';
2
- import { affixProps, useAffix, selectionProps, selectionEmits, useSelectionList, itemProps, useSelectionItem, iconProps, useIcon, switchProps, switchEmits, useSwitch } from '@hoci/core';
3
- import { capitalize as capitalize$1 } from 'tslx';
1
+ import { defineComponent, h, renderSlot, reactive, computed, provide, inject, KeepAlive, watch, Teleport } from 'vue';
2
+ import { affixProps, useAffix, selectionProps as selectionProps$1, selectionEmits as selectionEmits$1, useSelectionList as useSelectionList$1, itemProps as itemProps$1, useSelectionItem as useSelectionItem$1, iconProps, useIcon, switchProps, switchEmits, useSwitch, configProviderProps, provideSharedConfig, popoverProps, popoverEmits, usePopover } from '@hoci/core';
3
+ import { capitalize, cls } from 'tslx';
4
+ import { defineHookProps, valuePropType, classPropType, labelPropType, defineHookEmits, defineHookComponent, useSharedConfig, getFirstChilld } from '@hoci/shared';
5
+ import { syncRef, toReactive, isDefined, tryOnScopeDispose } from '@vueuse/core';
4
6
 
5
7
  const HiAffix = defineComponent({
6
8
  name: "HiAffix",
@@ -27,15 +29,15 @@ const HiAffix = defineComponent({
27
29
  const HiSelection = defineComponent({
28
30
  name: "HiSelection",
29
31
  props: {
30
- ...selectionProps,
32
+ ...selectionProps$1,
31
33
  as: {
32
34
  type: String,
33
35
  default: "div"
34
36
  }
35
37
  },
36
- emits: selectionEmits,
38
+ emits: selectionEmits$1,
37
39
  setup(props, context) {
38
- const { render } = useSelectionList(props, context);
40
+ const { render } = useSelectionList$1(props, context);
39
41
  return () => h(props.as, {}, render());
40
42
  }
41
43
  });
@@ -43,14 +45,14 @@ const HiSelection = defineComponent({
43
45
  const HiItem = defineComponent({
44
46
  name: "HiItem",
45
47
  props: {
46
- ...itemProps,
48
+ ...itemProps$1,
47
49
  as: {
48
50
  type: String,
49
51
  default: "div"
50
52
  }
51
53
  },
52
54
  setup(props, context) {
53
- const { render, activate, className, isDisabled, activateEvent } = useSelectionItem(
55
+ const { render, activate, className, isDisabled, activateEvent } = useSelectionItem$1(
54
56
  props,
55
57
  context
56
58
  );
@@ -102,7 +104,7 @@ const HiSwitch = defineComponent({
102
104
  props.as,
103
105
  {
104
106
  class: className.value,
105
- [`on${capitalize$1(activateEvent.value)}`]: toggle
107
+ [`on${capitalize(activateEvent.value)}`]: toggle
106
108
  },
107
109
  renderSlot(slots, "default", {
108
110
  active: modelValue.value,
@@ -113,13 +115,430 @@ const HiSwitch = defineComponent({
113
115
  }
114
116
  });
115
117
 
118
+ const HiConfigProvider = defineComponent({
119
+ props: {
120
+ ...configProviderProps,
121
+ as: {
122
+ type: String
123
+ }
124
+ },
125
+ setup(props, context) {
126
+ provideSharedConfig(props);
127
+ return () => {
128
+ const content = renderSlot(context.slots, "default", void 0);
129
+ if (props.as) {
130
+ return h(props.as, content);
131
+ }
132
+ return content;
133
+ };
134
+ }
135
+ });
136
+
137
+ const selectionProps = defineHookProps({
138
+ modelValue: {
139
+ type: valuePropType,
140
+ default: () => null
141
+ },
142
+ /**
143
+ * 选中时的 class
144
+ */
145
+ activeClass: {
146
+ type: classPropType,
147
+ default: "active"
148
+ },
149
+ /**
150
+ * 每个选项的 class
151
+ */
152
+ itemClass: {
153
+ type: classPropType,
154
+ default: ""
155
+ },
156
+ disabledClass: {
157
+ type: classPropType,
158
+ default: "disabled"
159
+ },
160
+ unactiveClass: {
161
+ type: classPropType,
162
+ default: ""
163
+ },
164
+ label: {
165
+ type: labelPropType
166
+ },
167
+ /**
168
+ * 多选模式
169
+ */
170
+ multiple: {
171
+ type: [Boolean, Number],
172
+ default: () => false
173
+ },
174
+ /**
175
+ * 可清除
176
+ */
177
+ clearable: {
178
+ type: Boolean
179
+ },
180
+ defaultValue: {
181
+ type: valuePropType,
182
+ default: () => null
183
+ },
184
+ activateEvent: {
185
+ type: String
186
+ }
187
+ });
188
+ const selectionEmits = defineHookEmits([
189
+ "update:modelValue",
190
+ "change",
191
+ "load",
192
+ "unload"
193
+ ]);
194
+ const HiSelectionContextSymbol = Symbol("[hi-selection]context");
195
+ function useSelectionContext() {
196
+ const sharedConfig = useSharedConfig();
197
+ return inject(HiSelectionContextSymbol, {
198
+ isActive: () => false,
199
+ changeActive: () => {
200
+ },
201
+ activeClass: "active",
202
+ unactiveClass: "unactive",
203
+ disabledClass: "disabled",
204
+ itemClass: "",
205
+ activateEvent: sharedConfig.activateEvent,
206
+ label: null,
207
+ multiple: false
208
+ });
209
+ }
210
+ const useSelectionList = defineHookComponent({
211
+ props: selectionProps,
212
+ emits: selectionEmits,
213
+ setup(props, { emit, slots }) {
214
+ const options = reactive([]);
215
+ function toArray(value) {
216
+ if (!isDefined(value)) {
217
+ return [];
218
+ }
219
+ if (props.multiple && Array.isArray(value)) {
220
+ return value.filter((v) => v != null || v !== void 0);
221
+ }
222
+ return [value];
223
+ }
224
+ const actives = reactive([
225
+ ...toArray(props.modelValue ?? props.defaultValue)
226
+ ]);
227
+ const currentValue = computed({
228
+ get() {
229
+ return props.multiple ? actives : actives[0];
230
+ },
231
+ set(val) {
232
+ actives.splice(0, actives.length, ...toArray(val));
233
+ }
234
+ });
235
+ const modelValue = computed({
236
+ get() {
237
+ return props.modelValue ?? props.defaultValue;
238
+ },
239
+ set(val) {
240
+ emit("update:modelValue", val);
241
+ }
242
+ });
243
+ syncRef(currentValue, modelValue, { immediate: true, deep: true });
244
+ const emitChange = () => emit("change", currentValue.value);
245
+ function isActive(value) {
246
+ return actives.includes(value);
247
+ }
248
+ function changeActive(value) {
249
+ if (isActive(value)) {
250
+ if (props.multiple || props.clearable) {
251
+ actives.splice(actives.indexOf(value), 1);
252
+ emitChange();
253
+ }
254
+ } else {
255
+ if (props.multiple) {
256
+ const limit = typeof props.multiple === "number" ? props.multiple : Number.POSITIVE_INFINITY;
257
+ if (actives.length < limit) {
258
+ actives.push(value);
259
+ emitChange();
260
+ }
261
+ } else {
262
+ actives.splice(0, actives.length, value);
263
+ emitChange();
264
+ }
265
+ }
266
+ }
267
+ const init = (option) => {
268
+ function remove() {
269
+ const index = options.findIndex((e) => e.id === option.id);
270
+ if (index > -1) {
271
+ options.splice(index, 1);
272
+ emit("unload", option);
273
+ }
274
+ }
275
+ for (let i = 0; i < options.length; i++) {
276
+ if (options[i].value === option.value) {
277
+ options.splice(i, 1);
278
+ i--;
279
+ }
280
+ }
281
+ options.push(option);
282
+ emit("load", option);
283
+ return remove;
284
+ };
285
+ const sharedConfig = useSharedConfig();
286
+ provide(HiSelectionContextSymbol, toReactive({
287
+ activeClass: computed(() => cls(props.activeClass)),
288
+ unactiveClass: computed(() => cls(props.unactiveClass)),
289
+ disabledClass: computed(() => cls(props.disabledClass)),
290
+ itemClass: computed(() => cls(props.itemClass)),
291
+ label: computed(() => props.label),
292
+ multiple: computed(() => props.multiple),
293
+ clearable: computed(() => props.clearable),
294
+ defaultValue: computed(() => props.defaultValue),
295
+ activateEvent: computed(() => props.activateEvent ?? sharedConfig.activateEvent),
296
+ active: currentValue,
297
+ changeActive,
298
+ isActive,
299
+ init
300
+ }));
301
+ const renderItem = () => {
302
+ const children = options.filter((e) => actives.includes(e.value)).map((e) => e.render());
303
+ return props.multiple ? children : getFirstChilld(children);
304
+ };
305
+ const slotData = {
306
+ isActive,
307
+ changeActive,
308
+ renderItem
309
+ };
310
+ const render = () => {
311
+ return renderSlot(slots, "default", slotData);
312
+ };
313
+ return {
314
+ options,
315
+ actives,
316
+ isActive,
317
+ changeActive,
318
+ renderItem,
319
+ render
320
+ };
321
+ }
322
+ });
323
+
324
+ const HiTabs = defineComponent({
325
+ props: {
326
+ ...selectionProps,
327
+ headerClass: {
328
+ type: classPropType
329
+ },
330
+ as: {
331
+ type: String,
332
+ default: "div"
333
+ },
334
+ headerAs: {
335
+ type: String,
336
+ default: "div"
337
+ },
338
+ contentAs: {
339
+ type: String,
340
+ default: "div"
341
+ },
342
+ contentClass: {
343
+ type: classPropType
344
+ },
345
+ keepAlive: {
346
+ type: [Boolean, Object],
347
+ default: false
348
+ }
349
+ },
350
+ setup(props, context) {
351
+ const selection = useSelectionList(props, context);
352
+ return () => {
353
+ let component = selection.renderItem();
354
+ if (props.keepAlive) {
355
+ component = h(KeepAlive, {
356
+ ...typeof props.keepAlive == "object" ? props.keepAlive : {}
357
+ }, component);
358
+ }
359
+ if (context.slots.content) {
360
+ component = context.slots.content({
361
+ component
362
+ });
363
+ } else {
364
+ component = h(props.contentAs, {
365
+ class: props.contentClass
366
+ }, component);
367
+ }
368
+ return h(props.as, [
369
+ h(props.headerAs, {
370
+ class: props.headerClass
371
+ }, renderSlot(context.slots, "default")),
372
+ component
373
+ ]);
374
+ };
375
+ }
376
+ });
377
+
378
+ const itemProps = defineHookProps({
379
+ value: {
380
+ type: valuePropType,
381
+ default() {
382
+ return Math.random().toString(16).slice(2);
383
+ }
384
+ },
385
+ label: {
386
+ type: [Function, String]
387
+ },
388
+ keepAlive: {
389
+ type: Boolean,
390
+ default: () => true
391
+ },
392
+ key: {
393
+ type: [String, Number, Symbol]
394
+ },
395
+ activateEvent: {
396
+ type: String
397
+ },
398
+ disabled: {
399
+ type: Boolean,
400
+ default: false
401
+ }
402
+ });
403
+ const useSelectionItem = defineHookComponent({
404
+ props: itemProps,
405
+ setup(props, { slots }) {
406
+ const context = useSelectionContext();
407
+ const activate = () => {
408
+ if (props.disabled) {
409
+ return;
410
+ }
411
+ context.changeActive(props.value);
412
+ };
413
+ const label = computed(() => {
414
+ let label2 = props.label ?? context.label;
415
+ if (label2 && typeof label2 == "function") {
416
+ label2 = label2(props.value);
417
+ }
418
+ return Array.isArray(label2) ? label2 : [label2];
419
+ });
420
+ function render() {
421
+ return slots.default?.({
422
+ active: context.isActive(props.value),
423
+ activate
424
+ }) ?? label.value.filter(Boolean);
425
+ }
426
+ let remove = () => {
427
+ };
428
+ const init = context.init;
429
+ if (init) {
430
+ watch(
431
+ () => props.value,
432
+ (value) => {
433
+ remove();
434
+ remove = init({
435
+ id: Math.random().toString(16).slice(2),
436
+ label: typeof props.label == "string" ? props.label : void 0,
437
+ value,
438
+ render
439
+ });
440
+ },
441
+ { immediate: true }
442
+ );
443
+ tryOnScopeDispose(remove);
444
+ }
445
+ const isActive = computed(() => context.isActive(props.value));
446
+ const isDisabled = computed(() => props.disabled);
447
+ const className = computed(() => {
448
+ const array = [context.itemClass];
449
+ if (!isDisabled.value) {
450
+ array.push(context.isActive(props.value) ? context.activeClass : context.unactiveClass);
451
+ } else {
452
+ array.push(context.disabledClass);
453
+ }
454
+ return cls(array);
455
+ });
456
+ const activateEvent = computed(() => props.activateEvent ?? context.activateEvent);
457
+ return {
458
+ activate,
459
+ render,
460
+ isActive,
461
+ isDisabled,
462
+ className,
463
+ activateEvent,
464
+ label
465
+ };
466
+ }
467
+ });
468
+
469
+ const HiTabPane = defineComponent({
470
+ props: {
471
+ ...itemProps
472
+ },
473
+ setup(props, context) {
474
+ const { className, activateEvent, activate, isDisabled, label } = useSelectionItem(props, context);
475
+ return () => {
476
+ return h(
477
+ "div",
478
+ {
479
+ class: className.value,
480
+ [`on${capitalize(activateEvent.value)}`]: activate,
481
+ disabled: isDisabled.value
482
+ },
483
+ label.value
484
+ );
485
+ };
486
+ }
487
+ });
488
+
489
+ const HiPopover = defineComponent({
490
+ name: "HiPopover",
491
+ props: {
492
+ ...popoverProps,
493
+ as: {
494
+ type: String,
495
+ default: "div"
496
+ }
497
+ },
498
+ emits: popoverEmits,
499
+ setup(props, context) {
500
+ const { triggerRef, popupClass, events, popupRef, popupStyle } = usePopover(props, context);
501
+ return () => {
502
+ let content = h(
503
+ "div",
504
+ {
505
+ class: popupClass.value,
506
+ style: popupStyle.value,
507
+ ref: popupRef
508
+ },
509
+ renderSlot(context.slots, "popup")
510
+ );
511
+ if (props.teleport) {
512
+ content = h(
513
+ Teleport,
514
+ {
515
+ to: props.teleport === true ? "body" : props.teleport
516
+ },
517
+ content
518
+ );
519
+ }
520
+ return h(props.as, {
521
+ ref: triggerRef,
522
+ ...events
523
+ }, [
524
+ renderSlot(context.slots, "default"),
525
+ content
526
+ ]);
527
+ };
528
+ }
529
+ });
530
+
116
531
  const components = {
117
532
  __proto__: null,
118
533
  HiAffix: HiAffix,
534
+ HiConfigProvider: HiConfigProvider,
119
535
  HiIcon: HiIcon,
120
536
  HiItem: HiItem,
537
+ HiPopover: HiPopover,
121
538
  HiSelection: HiSelection,
122
- HiSwitch: HiSwitch
539
+ HiSwitch: HiSwitch,
540
+ HiTabPane: HiTabPane,
541
+ HiTabs: HiTabs
123
542
  };
124
543
 
125
544
  const install = (app) => {
@@ -128,4 +547,4 @@ const install = (app) => {
128
547
  }
129
548
  };
130
549
 
131
- export { HiAffix, HiIcon, HiItem, HiSelection, HiSwitch, install };
550
+ export { HiAffix, HiConfigProvider, HiIcon, HiItem, HiPopover, HiSelection, HiSwitch, HiTabPane, HiTabs, install };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hoci/components",
3
- "version": "0.4.3",
3
+ "version": "0.5.1",
4
4
  "description": "",
5
5
  "author": "chizuki",
6
6
  "license": "MIT",
@@ -25,14 +25,14 @@
25
25
  "dist/"
26
26
  ],
27
27
  "peerDependencies": {
28
- "@vueuse/core": ">=10",
29
- "vue": "^3.3.4"
28
+ "vue": "^3.0.0-0"
30
29
  },
31
30
  "dependencies": {
32
- "@vueuse/core": "^10.5.0",
31
+ "@vueuse/core": ">=10.5.0",
33
32
  "maybe-types": "^0.1.0",
34
33
  "tslx": "^0.1.1",
35
- "@hoci/core": "0.4.3"
34
+ "@hoci/shared": "0.5.1",
35
+ "@hoci/core": "0.5.1"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "unbuild",