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