@v-c/picker 1.0.2 → 1.0.4-beta.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.
@@ -4,11 +4,11 @@ import { SelectorIdType } from './Selector/RangeSelector';
4
4
  export interface BaseRangePickerProps<DateType extends object> extends Omit<SharedPickerProps<DateType>, 'showTime' | 'id'> {
5
5
  id?: SelectorIdType;
6
6
  separator?: VueNode;
7
- value?: RangeValueType<DateType> | null;
8
- defaultValue?: RangeValueType<DateType>;
9
- onChange?: (dates: NoUndefinedRangeValueType<DateType> | null, dateStrings: [string, string]) => void;
10
- onCalendarChange?: (dates: NoUndefinedRangeValueType<DateType>, dateStrings: [string, string], info: BaseInfo) => void;
11
- onOk?: (values: NoUndefinedRangeValueType<DateType>) => void;
7
+ value?: RangeValueType<DateType | string> | null;
8
+ defaultValue?: RangeValueType<DateType | string>;
9
+ onChange?: (dates: NoUndefinedRangeValueType<DateType | string> | null, dateStrings: [string, string]) => void;
10
+ onCalendarChange?: (dates: NoUndefinedRangeValueType<DateType | string>, dateStrings: [string, string], info: BaseInfo) => void;
11
+ onOk?: (values: NoUndefinedRangeValueType<DateType | string>) => void;
12
12
  placeholder?: [string, string];
13
13
  /**
14
14
  * Config the popup panel date.
@@ -16,12 +16,12 @@ export interface BaseRangePickerProps<DateType extends object> extends Omit<Shar
16
16
  *
17
17
  * Note: `defaultPickerValue` priority is higher than `value` for the first open.
18
18
  */
19
- defaultPickerValue?: [DateType, DateType] | DateType | null;
19
+ defaultPickerValue?: [DateType | string, DateType | string] | DateType | string | null;
20
20
  /**
21
21
  * Config each start & end field popup panel date.
22
22
  * When config `pickerValue`, you must also provide `onPickerValueChange` to handle changes.
23
23
  */
24
- pickerValue?: [DateType, DateType] | DateType | null;
24
+ pickerValue?: [DateType | string, DateType | string] | DateType | string | null;
25
25
  /**
26
26
  * Each popup panel `pickerValue` includes `mode` change will trigger the callback.
27
27
  * @param date The changed picker value
@@ -3,6 +3,7 @@ import { providePickerContext } from "./context.js";
3
3
  import PickerTrigger_default from "../PickerTrigger/index.js";
4
4
  import { fillIndex, getFromDate, toArray } from "../utils/miscUtil.js";
5
5
  import { pickTriggerProps } from "../PickerTrigger/util.js";
6
+ import { formatValues } from "../utils/valueUtil.js";
6
7
  import useCellRender from "./hooks/useCellRender.js";
7
8
  import useFieldsInvalidate from "./hooks/useFieldsInvalidate.js";
8
9
  import useFilledProps from "./hooks/useFilledProps.js";
@@ -64,6 +65,7 @@ var RangePicker_default = /* @__PURE__ */ defineComponent((props, { expose }) =>
64
65
  const onPanelChange = computed(() => fp.value.onPanelChange);
65
66
  const onCalendarChange = computed(() => fp.value.onCalendarChange);
66
67
  const onOk = computed(() => fp.value.onOk);
68
+ const valueFormat = computed(() => fp.value.valueFormat);
67
69
  const defaultPickerValue = computed(() => fp.value.defaultPickerValue);
68
70
  const pickerValue = computed(() => fp.value.pickerValue);
69
71
  const onPickerValueChange = computed(() => fp.value.onPickerValueChange);
@@ -96,10 +98,18 @@ var RangePicker_default = /* @__PURE__ */ defineComponent((props, { expose }) =>
96
98
  if (disabled.value.some((fieldDisabled) => !fieldDisabled) || !nextOpen) setMergeOpen(nextOpen, config);
97
99
  };
98
100
  const onInternalCalendarChange = (dates, dateStrings, info) => {
99
- if (onCalendarChange.value) onCalendarChange.value(dates, dateStrings, info);
101
+ if (onCalendarChange.value) onCalendarChange.value(formatValues(dates, {
102
+ generateConfig: generateConfig.value,
103
+ locale: locale.value,
104
+ valueFormat: valueFormat.value
105
+ }), dateStrings, info);
100
106
  };
101
107
  const onInternalOk = (dates) => {
102
- onOk.value?.(dates);
108
+ onOk.value?.(formatValues(dates, {
109
+ generateConfig: generateConfig.value,
110
+ locale: locale.value,
111
+ valueFormat: valueFormat.value
112
+ }));
103
113
  };
104
114
  const [mergedValue, setInnerValue, getCalendarValue, triggerCalendarChange, triggerOk] = useInnerValue(generateConfig, locale, formatList, ref(true), ref(false), defaultValue, value, onInternalCalendarChange, onInternalOk);
105
115
  const calendarValue = computed(() => getCalendarValue.value);
@@ -132,7 +142,16 @@ var RangePicker_default = /* @__PURE__ */ defineComponent((props, { expose }) =>
132
142
  const internalMode = computed(() => mergedMode.value === "date" && mergedShowTime.value ? "datetime" : mergedMode.value);
133
143
  const multiplePanel = computed(() => internalMode.value === picker.value && internalMode.value !== "time");
134
144
  const mergedShowNow = useShowNow(picker, mergedMode, showNow, showToday, ref(true));
135
- const [flushSubmit, triggerSubmitChange] = useRangeValue(fp, mergedValue, setInnerValue, () => getCalendarValue.value, triggerCalendarChange, disabled, formatList, focused, mergedOpen, isInvalidateDate);
145
+ const [flushSubmit, triggerSubmitChange] = useRangeValue(computed(() => ({
146
+ ...fp.value,
147
+ onChange: (dates, dateStrings) => {
148
+ fp.value.onChange?.(formatValues(dates, {
149
+ generateConfig: generateConfig.value,
150
+ locale: locale.value,
151
+ valueFormat: valueFormat.value
152
+ }), dateStrings);
153
+ }
154
+ })), mergedValue, setInnerValue, () => getCalendarValue.value, triggerCalendarChange, disabled, formatList, focused, mergedOpen, isInvalidateDate);
136
155
  const mergedDisabledDate = useRangeDisabledDate(calendarValue, disabled, activeIndexList, generateConfig, locale, disabledDate);
137
156
  const [submitInvalidates, onSelectorInvalid] = useFieldsInvalidate(calendarValue, isInvalidateDate, allowEmpty);
138
157
  const [currentPickerValue, setCurrentPickerValue] = useRangePickerValue(generateConfig, locale, calendarValue, modes, mergedOpen, activeIndex, internalPicker, multiplePanel, defaultPickerValue, pickerValue, computed(() => mergedShowTime.value?.defaultOpenValue), onPickerValueChange, minDate, maxDate);
@@ -545,6 +564,11 @@ var RangePicker_default = /* @__PURE__ */ defineComponent((props, { expose }) =>
545
564
  required: false,
546
565
  default: void 0
547
566
  },
567
+ valueFormat: {
568
+ type: String,
569
+ required: false,
570
+ default: void 0
571
+ },
548
572
  prefix: {
549
573
  type: [
550
574
  Object,
@@ -6,12 +6,12 @@ export interface BasePickerProps<DateType extends object = any> extends SharedPi
6
6
  removeIcon?: any;
7
7
  /** Only work when `multiple` is in used */
8
8
  maxTagCount?: number | 'responsive';
9
- value?: DateType | DateType[] | null;
10
- defaultValue?: DateType | DateType[];
11
- onChange?: (date: DateType | DateType[] | null, dateString: string | string[]) => void;
12
- onCalendarChange?: (date: DateType | DateType[], dateString: string | string[], info: BaseInfo) => void;
9
+ value?: DateType | DateType[] | string | string[] | null;
10
+ defaultValue?: DateType | DateType[] | string | string[];
11
+ onChange?: (date: DateType | DateType[] | string | string[] | null, dateString: string | string[]) => void;
12
+ onCalendarChange?: (date: DateType | DateType[] | string | string[], dateString: string | string[], info: BaseInfo) => void;
13
13
  /** */
14
- onOk?: (value?: DateType | DateType[]) => void;
14
+ onOk?: (value?: DateType | DateType[] | string | string[]) => void;
15
15
  placeholder?: string;
16
16
  /**
17
17
  * Config the popup panel date.
@@ -19,12 +19,12 @@ export interface BasePickerProps<DateType extends object = any> extends SharedPi
19
19
  *
20
20
  * Note: `defaultPickerValue` priority is higher than `value` for the first open.
21
21
  */
22
- defaultPickerValue?: DateType | null;
22
+ defaultPickerValue?: DateType | string | null;
23
23
  /**
24
24
  * Config each start & end field popup panel date.
25
25
  * When config `pickerValue`, you must also provide `onPickerValueChange` to handle changes.
26
26
  */
27
- pickerValue?: DateType | null;
27
+ pickerValue?: DateType | string | null;
28
28
  /**
29
29
  * Each popup panel `pickerValue` change will trigger the callback.
30
30
  * @param date The changed picker value
@@ -3,6 +3,7 @@ import { providePickerContext } from "./context.js";
3
3
  import PickerTrigger_default from "../PickerTrigger/index.js";
4
4
  import { toArray } from "../utils/miscUtil.js";
5
5
  import { pickTriggerProps } from "../PickerTrigger/util.js";
6
+ import { formatValue, formatValues } from "../utils/valueUtil.js";
6
7
  import useCellRender from "./hooks/useCellRender.js";
7
8
  import useFieldsInvalidate from "./hooks/useFieldsInvalidate.js";
8
9
  import useFilledProps from "./hooks/useFilledProps.js";
@@ -49,6 +50,7 @@ var SinglePicker_default = /* @__PURE__ */ defineComponent((props, { expose }) =
49
50
  const onPanelChange = computed(() => fp.value.onPanelChange);
50
51
  const onCalendarChange = computed(() => fp.value.onCalendarChange);
51
52
  const onOk = computed(() => fp.value.onOk);
53
+ const valueFormat = computed(() => fp.value.valueFormat);
52
54
  const multiple = computed(() => fp.value.multiple);
53
55
  const defaultPickerValue = computed(() => fp.value.defaultPickerValue);
54
56
  const pickerValue = computed(() => fp.value.pickerValue);
@@ -87,6 +89,16 @@ var SinglePicker_default = /* @__PURE__ */ defineComponent((props, { expose }) =
87
89
  if (values === null) return null;
88
90
  return multiple.value ? values : values[0];
89
91
  }
92
+ const toValueByFormat = (values) => {
93
+ const parsed = pickerParam(values);
94
+ const config = {
95
+ generateConfig: generateConfig.value,
96
+ locale: locale.value,
97
+ valueFormat: valueFormat.value
98
+ };
99
+ if (Array.isArray(parsed)) return formatValues(parsed, config);
100
+ return formatValue(parsed, config);
101
+ };
90
102
  const toggleDates = useToggleDates(generateConfig, locale, internalPicker);
91
103
  const semanticCtx = useSemantic(classNames, styles);
92
104
  const [mergedOpen, triggerOpen] = useOpen(open, defaultOpen, computed(() => [disabled.value]), (open$1) => {
@@ -96,11 +108,11 @@ var SinglePicker_default = /* @__PURE__ */ defineComponent((props, { expose }) =
96
108
  if (onCalendarChange.value) {
97
109
  const filteredInfo = { ...info };
98
110
  delete filteredInfo.range;
99
- onCalendarChange.value(pickerParam(dates), pickerParam(dateStrings), filteredInfo);
111
+ onCalendarChange.value(toValueByFormat(dates), pickerParam(dateStrings), filteredInfo);
100
112
  }
101
113
  };
102
114
  const onInternalOk = (dates) => {
103
- onOk.value?.(pickerParam(dates));
115
+ onOk.value?.(toValueByFormat(dates));
104
116
  };
105
117
  const [mergedValue, setInnerValue, getCalendarValue, triggerCalendarChange, triggerOk] = useInnerValue(generateConfig, locale, formatList, ref(false), order, defaultValue, value, onInternalCalendarChange, onInternalOk);
106
118
  const calendarValue = computed(() => getCalendarValue.value);
@@ -123,7 +135,7 @@ var SinglePicker_default = /* @__PURE__ */ defineComponent((props, { expose }) =
123
135
  const internalMode = computed(() => mergedMode.value === "date" && showTime.value ? "datetime" : mergedMode.value);
124
136
  const mergedShowNow = useShowNow(picker, mergedMode, showNow, showToday);
125
137
  const onInternalChange = (dates, dateStrings) => {
126
- if (props?.onChange) props?.onChange?.(pickerParam(dates), pickerParam(dateStrings));
138
+ if (props?.onChange) props?.onChange?.(toValueByFormat(dates), pickerParam(dateStrings));
127
139
  };
128
140
  const [, triggerSubmitChange] = useRangeValue(computed(() => {
129
141
  return {
@@ -521,6 +533,11 @@ var SinglePicker_default = /* @__PURE__ */ defineComponent((props, { expose }) =
521
533
  required: false,
522
534
  default: void 0
523
535
  },
536
+ valueFormat: {
537
+ type: String,
538
+ required: false,
539
+ default: void 0
540
+ },
524
541
  prefix: {
525
542
  type: [
526
543
  Object,
@@ -1,4 +1,5 @@
1
1
  import { toArray } from "../../utils/miscUtil.js";
2
+ import { parseValue } from "../../utils/valueUtil.js";
2
3
  import useLocale from "../../hooks/useLocale.js";
3
4
  import { fillShowTimeConfig, getTimeProps } from "../../hooks/useTimeConfig.js";
4
5
  import { fillClearIcon } from "../Selector/hooks/useClearIcon.js";
@@ -8,10 +9,10 @@ import useInputReadOnly from "./useInputReadOnly.js";
8
9
  import useInvalidate from "./useInvalidate.js";
9
10
  import { computed } from "vue";
10
11
  import { warning } from "@v-c/util";
11
- function useList(value, fillMode = false) {
12
+ function useList(value, fillMode = false, transform) {
12
13
  return computed(() => {
13
14
  const val = value.value;
14
- const list = val ? toArray(val) : val;
15
+ const list = val === null || val === void 0 ? val : toArray(val).map((item) => transform ? transform(item) : item);
15
16
  if (fillMode && list && Array.isArray(list)) {
16
17
  const clone = [...list];
17
18
  clone[1] = clone[1] || clone[0];
@@ -31,10 +32,6 @@ function useFilledProps(props, updater) {
31
32
  input: props.value.inputRender,
32
33
  ...props.value.components
33
34
  }));
34
- const values = useList(computed(() => props.value.value));
35
- const defaultValues = useList(computed(() => props.value.defaultValue));
36
- const pickerValues = useList(computed(() => props.value.pickerValue));
37
- const defaultPickerValues = useList(computed(() => props.value.defaultPickerValue));
38
35
  const internalPicker = computed(() => mergedPicker.value === "date" && props.value.showTime ? "datetime" : mergedPicker.value);
39
36
  const multipleInteractivePicker = computed(() => internalPicker.value === "time" || internalPicker.value === "datetime");
40
37
  const complexPicker = computed(() => multipleInteractivePicker.value || props.value.multiple);
@@ -47,7 +44,17 @@ function useFilledProps(props, updater) {
47
44
  const showTimeFormat = computed(() => timePropsInfo.value[2]);
48
45
  const propFormat = computed(() => timePropsInfo.value[3]);
49
46
  const mergedLocale = useLocale(computed(() => props.value.locale), localeTimeProps);
47
+ const valueFormat = computed(() => props.value.valueFormat);
48
+ const parseByValueFormat = (val) => parseValue(val, {
49
+ generateConfig: props.value.generateConfig,
50
+ locale: mergedLocale.value,
51
+ valueFormat: valueFormat.value
52
+ });
50
53
  const mergedShowTime = computed(() => fillShowTimeConfig(internalPicker.value, showTimeFormat.value, propFormat.value, timeProps.value, mergedLocale.value));
54
+ const values = useList(computed(() => props.value.value), false, parseByValueFormat);
55
+ const defaultValues = useList(computed(() => props.value.defaultValue), false, parseByValueFormat);
56
+ const pickerValues = useList(computed(() => props.value.pickerValue), false, parseByValueFormat);
57
+ const defaultPickerValues = useList(computed(() => props.value.defaultPickerValue), false, parseByValueFormat);
51
58
  if (process.env.NODE_ENV !== "production") {
52
59
  if (mergedPicker.value === "time") {
53
60
  if ([
@@ -6,7 +6,7 @@ type TriggerCalendarChange<ValueType extends object[]> = (calendarValues: ValueT
6
6
  * Control the internal `value` align with prop `value` and provide a temp `calendarValue` for ui.
7
7
  * `calendarValue` will be reset when blur & focus & open.
8
8
  */
9
- export declare function useInnerValue<ValueType extends DateType[], DateType extends object = any>(generateConfig: Ref<GenerateConfig<DateType>>, locale: Ref<Locale>, formatList: Ref<FormatType[]>, rangeValue: Ref<boolean | undefined>, order: Ref<boolean | undefined>, defaultValue: Ref<ValueType | undefined>, value: Ref<ValueType | undefined>, onCalendarChange?: (dates: ValueType, dateStrings: [string, string], info: BaseInfo) => void, onOk?: (dates: ValueType) => void): readonly [ComputedRef<ValueType>, (val: ValueType) => void, Ref<ValueType, ValueType>, TriggerCalendarChange<ValueType>, () => void];
9
+ export declare function useInnerValue<ValueType extends DateType[], DateType extends object = any>(generateConfig: Ref<GenerateConfig<DateType>>, locale: Ref<Locale>, formatList: Ref<FormatType[]>, rangeValue: Ref<boolean | undefined>, order: Ref<boolean | undefined>, defaultValue: Ref<ValueType | undefined>, value: Ref<ValueType | undefined>, onCalendarChange?: (dates: ValueType, dateStrings: [string, string], info: BaseInfo) => void, onOk?: (dates: ValueType) => void): any;
10
10
  export default function useRangeValue<ValueType extends DateType[], DateType extends object = any>(info: ComputedRef<{
11
11
  generateConfig: GenerateConfig<DateType>;
12
12
  locale: Locale;
@@ -1,7 +1,7 @@
1
1
  import { fillIndex } from "../../utils/miscUtil.js";
2
2
  import { formatValue, isSame, isSameTimestamp } from "../../utils/dateUtil.js";
3
3
  import useLockEffect from "./useLockEffect.js";
4
- import { computed, ref, watch } from "vue";
4
+ import { computed, ref, shallowRef, watch } from "vue";
5
5
  var EMPTY_VALUE = [];
6
6
  function useUtil(generateConfig, locale, formatList) {
7
7
  const getDateTexts = (dates) => {
@@ -30,12 +30,12 @@ function orderDates(dates, generateConfig) {
30
30
  return [...dates].sort((a, b) => generateConfig.isAfter(a, b) ? 1 : -1);
31
31
  }
32
32
  function useInnerValue(generateConfig, locale, formatList, rangeValue, order, defaultValue, value, onCalendarChange, onOk) {
33
- const internalValue = ref(defaultValue.value);
34
- const mergedValue = computed(() => {
35
- return (value.value !== void 0 ? value.value : internalValue.value) || EMPTY_VALUE;
33
+ const mergedValue = shallowRef((value.value === void 0 ? defaultValue.value : value.value) || EMPTY_VALUE);
34
+ watch(value, (value$1) => {
35
+ mergedValue.value = value$1 || EMPTY_VALUE;
36
36
  });
37
37
  const setInnerValue = (val) => {
38
- if (value.value === void 0) internalValue.value = val;
38
+ if (value.value === void 0) mergedValue.value = val;
39
39
  };
40
40
  const calendarValue = ref(mergedValue.value);
41
41
  watch(mergedValue, (val) => {
@@ -239,6 +239,11 @@ export interface SharedPickerProps<DateType extends object = any> extends Shared
239
239
  format: string;
240
240
  type?: 'mask';
241
241
  };
242
+ /**
243
+ * Use this format to parse incoming string value and format outgoing callback value.
244
+ * This only affects the first argument in `onChange` / `onCalendarChange` / `onOk`.
245
+ */
246
+ valueFormat?: string;
242
247
  prefix?: VueNode;
243
248
  suffixIcon?: VueNode;
244
249
  allowClear?: boolean | {
@@ -0,0 +1,12 @@
1
+ import { GenerateConfig } from '../generate';
2
+ import { Locale } from '../interface';
3
+ interface ValueFormatConfig<DateType> {
4
+ generateConfig: GenerateConfig<DateType>;
5
+ locale: Locale;
6
+ valueFormat?: string;
7
+ }
8
+ export declare function parseValue<DateType>(value: DateType | string | null | undefined, config: ValueFormatConfig<DateType>): DateType | null | undefined;
9
+ export declare function parseValues<DateType>(values: (DateType | string | null | undefined)[] | null | undefined, config: ValueFormatConfig<DateType>): (DateType | null | undefined)[] | null | undefined;
10
+ export declare function formatValue<DateType>(value: DateType | null | undefined, config: ValueFormatConfig<DateType>): DateType | string | null | undefined;
11
+ export declare function formatValues<DateType>(values: (DateType | null | undefined)[] | null | undefined, config: ValueFormatConfig<DateType>): (string | DateType | null | undefined)[] | null | undefined;
12
+ export {};
@@ -0,0 +1,21 @@
1
+ function parseValue(value, config) {
2
+ const { valueFormat, generateConfig, locale } = config;
3
+ if (!valueFormat || typeof value !== "string") return value;
4
+ const parsed = generateConfig.locale.parse(locale.locale, value, [valueFormat]);
5
+ if (parsed && generateConfig.isValidate(parsed)) return parsed;
6
+ return null;
7
+ }
8
+ function parseValues(values, config) {
9
+ if (!values) return values;
10
+ return values.map((value) => parseValue(value, config));
11
+ }
12
+ function formatValue(value, config) {
13
+ const { valueFormat, generateConfig, locale } = config;
14
+ if (!valueFormat || value === null || value === void 0) return value;
15
+ return generateConfig.locale.format(locale.locale, value, valueFormat);
16
+ }
17
+ function formatValues(values, config) {
18
+ if (!values) return values;
19
+ return values.map((value) => formatValue(value, config));
20
+ }
21
+ export { formatValue, formatValues, parseValue, parseValues };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@v-c/picker",
3
3
  "type": "module",
4
- "version": "1.0.2",
4
+ "version": "1.0.4-beta.1",
5
5
  "description": "picker ui component for vue",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -73,9 +73,9 @@
73
73
  },
74
74
  "dependencies": {
75
75
  "@v-c/overflow": "^1.0.3",
76
- "@v-c/resize-observer": "^1.0.8",
77
- "@v-c/trigger": "^1.0.10",
78
- "@v-c/util": "^1.0.13"
76
+ "@v-c/trigger": "^1.0.11",
77
+ "@v-c/util": "^1.0.14",
78
+ "@v-c/resize-observer": "^1.0.8"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@types/luxon": "^3.7.1"