@antify/ui 4.1.32 → 4.1.34

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.
@@ -35,11 +35,16 @@ const props = withDefaults(defineProps<{
35
35
  date: string;
36
36
  color: string;
37
37
  }[];
38
+ /**
39
+ * Color token used for the week number column (e.g., 'base-200', 'primary-500').
40
+ */
41
+ weekNumberColor?: string;
38
42
  }>(), {
39
43
  showWeekend: false,
40
44
  showWeekNumbers: false,
41
45
  skeleton: false,
42
46
  specialDays: () => [],
47
+ weekNumberColor: 'base-200',
43
48
  });
44
49
  const emit = defineEmits([
45
50
  'select',
@@ -134,6 +139,18 @@ const getColorNumber = (color: string) => {
134
139
  return match ? parseInt(match[0], 10) : null;
135
140
  };
136
141
 
142
+ const getContrastTextColor = (colorToken: string) => {
143
+ const match = colorToken.match(/(\d+)/);
144
+ const weight = match ? parseInt(match[0], 10) : 0;
145
+
146
+ return weight < 500 ? 'var(--color-for-white-bg-font)' : '#fff';
147
+ };
148
+
149
+ const weekNumberStyles = computed(() => ({
150
+ backgroundColor: `var(--color-${props.weekNumberColor})`,
151
+ color: getContrastTextColor(props.weekNumberColor),
152
+ }));
153
+
137
154
  watch(() => props.modelValue, (val) => {
138
155
  const date = new Date(val);
139
156
  currentMonthIndex.value = date.getMonth();
@@ -179,9 +196,11 @@ onMounted(() => {
179
196
  }"
180
197
  >
181
198
  <div
182
- v-for="day in weekDays"
183
- :key="day"
184
- class="text-for-white-bg-font text-center flex items-center justify-center"
199
+ v-for="(day, index) in weekDays"
200
+ :key="`${day}-${index}`"
201
+ class="text-center flex items-center justify-center rounded-md"
202
+ :class="[!(showWeekNumbers && index === 0) ? 'text-for-white-bg-font' : '']"
203
+ :style="showWeekNumbers && index === 0 ? weekNumberStyles : {}"
185
204
  >
186
205
  <AntSkeleton
187
206
  :visible="skeleton"
@@ -200,7 +219,8 @@ onMounted(() => {
200
219
  >
201
220
  <div
202
221
  v-if="showWeekNumbers"
203
- class="flex text-base-500 font-semibold bg-base-100 rounded-md"
222
+ class="flex font-semibold rounded-md transition-colors"
223
+ :style="weekNumberStyles"
204
224
  >
205
225
  <AntSkeleton
206
226
  :visible="skeleton"
@@ -4,4 +4,5 @@ declare const meta: Meta<typeof AntCalendar>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof AntCalendar>;
6
6
  export declare const Docs: Story;
7
+ export declare const WeekNumberStyling: Story;
7
8
  export declare const Summary: Story;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- module.exports = exports.Summary = exports.Docs = void 0;
6
+ module.exports = exports.WeekNumberStyling = exports.Summary = exports.Docs = void 0;
7
7
  var _AntDatePicker = _interopRequireDefault(require("../AntDatePicker.vue"));
8
8
  var _AntDateSwitcher = _interopRequireDefault(require("../AntDateSwitcher.vue"));
9
9
  var _vue = require("vue");
@@ -31,6 +31,21 @@ const meta = {
31
31
  }
32
32
  }
33
33
  },
34
+ weekNumberColor: {
35
+ control: "text",
36
+ description: "Color token e.g. 'base-200', 'primary-500'. Automatically calculates contrast text color.",
37
+ table: {
38
+ type: {
39
+ summary: "string"
40
+ },
41
+ defaultValue: {
42
+ summary: "base-200"
43
+ }
44
+ }
45
+ },
46
+ showWeekNumbers: {
47
+ control: "boolean"
48
+ },
34
49
  onSelect: {
35
50
  action: "select"
36
51
  }
@@ -66,6 +81,65 @@ const Docs = exports.Docs = {
66
81
  }]
67
82
  }
68
83
  };
84
+ const WeekNumberStyling = exports.WeekNumberStyling = {
85
+ render: args => ({
86
+ components: {
87
+ AntCalendar: _AntDatePicker.default,
88
+ AntFormGroup: _AntFormGroup.default,
89
+ AntFormGroupLabel: _AntFormGroupLabel.default
90
+ },
91
+ setup() {
92
+ const value = (0, _vue.ref)((/* @__PURE__ */new Date("2026-01-01")).getTime());
93
+ return {
94
+ value,
95
+ args
96
+ };
97
+ },
98
+ template: `
99
+ <AntFormGroup class="p-4 flex gap-4 w-fit">
100
+ <AntFormGroupLabel>Week Number Styling (Presets)</AntFormGroupLabel>
101
+
102
+ <AntFormGroup class="grid grid-cols-4 gap-10">
103
+ <div class="flex flex-col w-64 gap-2">
104
+ <span class="text-sm font-medium text-for-white-bg-font">1. Default (Base 200)</span>
105
+ <AntCalendar
106
+ v-model="value"
107
+ :show-week-numbers="true"
108
+ />
109
+ </div>
110
+
111
+ <div class="flex flex-col w-64 gap-2">
112
+ <span class="text-sm font-medium text-for-white-bg-font">2. Primary 900</span>
113
+ <AntCalendar
114
+ v-model="value"
115
+ :show-week-numbers="true"
116
+ week-number-color="primary-900"
117
+ />
118
+ </div>
119
+
120
+ <div class="flex flex-col w-64 gap-2">
121
+ <span class="text-sm font-medium text-for-white-bg-font">3. Info 100</span>
122
+ <AntCalendar
123
+ v-model="value"
124
+ :show-week-numbers="true"
125
+ week-number-color="info-100"
126
+ />
127
+ </div>
128
+
129
+ <div class="flex flex-col w-64 gap-2">
130
+ <span class="text-sm font-medium text-for-white-bg-font">4. Success 500</span>
131
+ <AntCalendar
132
+ v-model="value"
133
+ :show-week-numbers="true"
134
+ week-number-color="success-500"
135
+ />
136
+ </div>
137
+
138
+ </AntFormGroup>
139
+ </AntFormGroup>
140
+ `
141
+ })
142
+ };
69
143
  const Summary = exports.Summary = {
70
144
  parameters: {
71
145
  chromatic: {
@@ -29,6 +29,21 @@ const meta = {
29
29
  }
30
30
  }
31
31
  },
32
+ weekNumberColor: {
33
+ control: "text",
34
+ description: "Color token e.g. 'base-200', 'primary-500'. Automatically calculates contrast text color.",
35
+ table: {
36
+ type: {
37
+ summary: "string"
38
+ },
39
+ defaultValue: {
40
+ summary: "base-200"
41
+ }
42
+ }
43
+ },
44
+ showWeekNumbers: {
45
+ control: "boolean"
46
+ },
32
47
  onSelect: {
33
48
  action: "select"
34
49
  }
@@ -66,6 +81,65 @@ export const Docs = {
66
81
  ]
67
82
  }
68
83
  };
84
+ export const WeekNumberStyling = {
85
+ render: (args) => ({
86
+ components: {
87
+ AntCalendar,
88
+ AntFormGroup,
89
+ AntFormGroupLabel
90
+ },
91
+ setup() {
92
+ const value = ref((/* @__PURE__ */ new Date("2026-01-01")).getTime());
93
+ return {
94
+ value,
95
+ args
96
+ };
97
+ },
98
+ template: `
99
+ <AntFormGroup class="p-4 flex gap-4 w-fit">
100
+ <AntFormGroupLabel>Week Number Styling (Presets)</AntFormGroupLabel>
101
+
102
+ <AntFormGroup class="grid grid-cols-4 gap-10">
103
+ <div class="flex flex-col w-64 gap-2">
104
+ <span class="text-sm font-medium text-for-white-bg-font">1. Default (Base 200)</span>
105
+ <AntCalendar
106
+ v-model="value"
107
+ :show-week-numbers="true"
108
+ />
109
+ </div>
110
+
111
+ <div class="flex flex-col w-64 gap-2">
112
+ <span class="text-sm font-medium text-for-white-bg-font">2. Primary 900</span>
113
+ <AntCalendar
114
+ v-model="value"
115
+ :show-week-numbers="true"
116
+ week-number-color="primary-900"
117
+ />
118
+ </div>
119
+
120
+ <div class="flex flex-col w-64 gap-2">
121
+ <span class="text-sm font-medium text-for-white-bg-font">3. Info 100</span>
122
+ <AntCalendar
123
+ v-model="value"
124
+ :show-week-numbers="true"
125
+ week-number-color="info-100"
126
+ />
127
+ </div>
128
+
129
+ <div class="flex flex-col w-64 gap-2">
130
+ <span class="text-sm font-medium text-for-white-bg-font">4. Success 500</span>
131
+ <AntCalendar
132
+ v-model="value"
133
+ :show-week-numbers="true"
134
+ week-number-color="success-500"
135
+ />
136
+ </div>
137
+
138
+ </AntFormGroup>
139
+ </AntFormGroup>
140
+ `
141
+ })
142
+ };
69
143
  export const Summary = {
70
144
  parameters: {
71
145
  chromatic: {
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" setup>
2
2
  import {
3
- computed, onMounted,
3
+ computed, onMounted, nextTick, ref, useId,
4
4
  } from 'vue';
5
5
  import AntButton from '../AntButton.vue';
6
6
  import AntField from '../forms/AntField.vue';
@@ -58,6 +58,7 @@ const props = withDefaults(defineProps<{
58
58
  messages?: string[];
59
59
  indicators?: boolean;
60
60
  inputRef?: HTMLInputElement | null;
61
+ selectAllOnFocus?: boolean;
61
62
  }>(), {
62
63
  state: InputState.base,
63
64
  disabled: false,
@@ -69,95 +70,197 @@ const props = withDefaults(defineProps<{
69
70
  messages: () => [],
70
71
  indicators: false,
71
72
  inputRef: null,
73
+ selectAllOnFocus: false,
72
74
  });
73
75
  const emit = defineEmits([
74
76
  'update:modelValue',
75
77
  'update:inputRef',
76
78
  'validate',
79
+ 'focus',
80
+ 'blur',
77
81
  ]);
78
82
 
83
+ const id = useId();
84
+ const _inputRef = useVModel(props, 'inputRef', emit);
85
+ const isFocused = ref(false);
86
+
79
87
  const _modelValue = computed({
80
88
  get: () => {
81
- if(!props.modelValue) {
82
- return props.modelValue;
89
+ if (props.modelValue === null || props.modelValue === undefined || props.modelValue === '') {
90
+ return null;
83
91
  }
84
92
 
85
- const modelDecimalPlaces = getDecimalPlaces(props.modelValue || 0);
86
- const stepDecimalPlaces = getDecimalPlaces(props.steps);
87
- const decimalPlaces = Math.max(modelDecimalPlaces, stepDecimalPlaces);
93
+ if (isFocused.value) {
94
+ return props.modelValue.toString();
95
+ }
88
96
 
89
- return String(new Big(props.modelValue).toFixed(decimalPlaces));
97
+ const bigValue = new Big(props.modelValue);
98
+ const isInteger = bigValue.mod(1).eq(0);
99
+
100
+ if (isInteger) {
101
+ return props.modelValue.toString();
102
+ }
103
+
104
+ const dp = getPrecision();
105
+
106
+ return bigValue.toFixed(dp);
90
107
  },
91
- set: (val: string) => {
92
- emit('update:modelValue', Number(val));
108
+ set: (val: string | number | null) => {
109
+ if (val === '' || val === null || val === undefined) {
110
+ emit('update:modelValue', null);
111
+
112
+ return;
113
+ }
114
+
115
+ const num = Number(val);
116
+ if (!isNaN(num)) {
117
+ emit('update:modelValue', num);
118
+ }
93
119
  },
94
120
  });
95
- const _inputRef = useVModel(props, 'inputRef', emit);
121
+
122
+ function onInputFocus(e: FocusEvent) {
123
+ isFocused.value = true;
124
+
125
+ const el = e.target as HTMLInputElement;
126
+
127
+ if (el && props.selectAllOnFocus && el.value !== '') {
128
+ const originalType = el.type;
129
+ el.type = 'text';
130
+
131
+ setTimeout(() => {
132
+ el.setSelectionRange(0, el.value.length);
133
+ el.type = originalType;
134
+ }, 0);
135
+ }
136
+ emit('focus', e);
137
+ }
138
+
139
+ function getPrecision() {
140
+ const modelDecimalPlaces = getDecimalPlaces(props.modelValue || 0);
141
+ const stepDecimalPlaces = getDecimalPlaces(props.steps);
142
+
143
+ return Math.max(modelDecimalPlaces, stepDecimalPlaces);
144
+ }
145
+
146
+ function subtract() {
147
+ const dp = getPrecision();
148
+
149
+ const current = props.modelValue !== null ? new Big(props.modelValue) : new Big(props.max || 0);
150
+ let result = current.sub(props.steps);
151
+
152
+ if (props.min !== undefined && result.lt(props.min)) {
153
+ result = new Big(props.min);
154
+ }
155
+
156
+ emit('update:modelValue', Number(result.toFixed(dp)));
157
+ }
158
+
159
+ function add() {
160
+ const dp = getPrecision();
161
+
162
+ const current = props.modelValue !== null ? new Big(props.modelValue) : new Big(props.min || 0);
163
+ let result = current.add(props.steps);
164
+
165
+ if (props.max !== undefined && result.gt(props.max)) {
166
+ result = new Big(props.max);
167
+ }
168
+
169
+ emit('update:modelValue', Number(result.toFixed(dp)));
170
+ }
96
171
 
97
172
  const isPrevButtonDisabled = computed(() => {
98
- if (props.disabled) {
173
+ if (props.disabled || props.readonly) {
99
174
  return true;
100
175
  }
101
176
 
102
- if (_modelValue.value === null) {
177
+ if (props.modelValue === null) {
103
178
  return false;
104
179
  }
105
180
 
106
- return props.min !== undefined ? Number(_modelValue.value) <= props.min : false;
181
+ return props.min !== undefined ? Number(props.modelValue) <= props.min : false;
107
182
  });
183
+
108
184
  const isNextButtonDisabled = computed(() => {
109
- if (props.disabled) {
185
+ if (props.disabled || props.readonly) {
110
186
  return true;
111
187
  }
112
188
 
113
- if (_modelValue.value === null) {
189
+ if (props.modelValue === null) {
114
190
  return false;
115
191
  }
116
192
 
117
- return props.max !== undefined ? Number(_modelValue.value) >= props.max : false;
193
+ return props.max !== undefined ? Number(props.modelValue) >= props.max : false;
118
194
  });
119
195
 
120
- onMounted(() => {
121
- handleEnumValidation(props.size, Size, 'size');
122
- handleEnumValidation(props.state, InputState, 'state');
123
- });
196
+ function onButtonBlur(e: FocusEvent) {
197
+ isFocused.value = false;
124
198
 
125
- function subtract() {
126
- const modelDecimalPlaces = getDecimalPlaces(_modelValue.value || 0);
127
- const stepDecimalPlaces = getDecimalPlaces(props.steps);
128
- const decimalPlaces = Math.max(modelDecimalPlaces, stepDecimalPlaces);
129
-
130
- if (_modelValue.value === null) {
131
- _modelValue.value = String(props.max || new Big(0).toFixed(decimalPlaces));
132
- } else if (props.max !== undefined && Number(_modelValue.value) - props.steps > props.max) {
133
- _modelValue.value = String(props.max);
134
- } else {
135
- _modelValue.value = new Big(_modelValue.value).sub(props.steps).toFixed(decimalPlaces);
199
+ if (props.modelValue !== null) {
200
+ let finalValue = props.modelValue;
201
+ const dp = getPrecision();
202
+
203
+ if (props.max !== undefined && finalValue > props.max) {
204
+ finalValue = props.max;
205
+ }
206
+ if (props.min !== undefined && finalValue < props.min) {
207
+ finalValue = props.min;
208
+ }
209
+
210
+ const roundedValue = Number(new Big(finalValue).toFixed(dp));
211
+
212
+ emit('update:modelValue', roundedValue);
213
+
214
+ if (_inputRef.value) {
215
+ _inputRef.value.value = roundedValue.toString();
216
+ }
217
+
218
+ emit('validate', roundedValue);
136
219
  }
220
+
221
+ emit('blur', e);
137
222
  }
138
223
 
139
- function add() {
140
- const modelDecimalPlaces = getDecimalPlaces(_modelValue.value || 0);
141
- const stepDecimalPlaces = getDecimalPlaces(props.steps);
142
- const decimalPlaces = Math.max(modelDecimalPlaces, stepDecimalPlaces);
143
-
144
- if (_modelValue.value === null) {
145
- return _modelValue.value = String(props.min || new Big(0).toFixed(decimalPlaces));
146
- } else if (props.min !== undefined && Number(_modelValue.value) + props.steps < props.min) {
147
- return _modelValue.value = String(props.min);
148
- } else {
149
- _modelValue.value = new Big(_modelValue.value).add(props.steps).toFixed(decimalPlaces);
224
+ function onKeyDown(e: KeyboardEvent) {
225
+ if (e.ctrlKey || e.metaKey) {
226
+ return;
227
+ }
228
+
229
+ const allowedKeys = [
230
+ 'Backspace',
231
+ 'Delete',
232
+ 'Tab',
233
+ 'Escape',
234
+ 'Enter',
235
+ 'ArrowLeft',
236
+ 'ArrowRight',
237
+ 'ArrowUp',
238
+ 'ArrowDown',
239
+ 'Home',
240
+ 'End',
241
+ ];
242
+
243
+ if (allowedKeys.includes(e.key)) {
244
+ return;
150
245
  }
151
- }
152
246
 
153
- function onButtonBlur() {
154
- emit('validate', _modelValue.value);
247
+ if (!/^[0-9.-]$/.test(e.key)) {
248
+ e.preventDefault();
249
+
250
+ return;
251
+ }
155
252
  }
253
+
254
+ onMounted(() => {
255
+ handleEnumValidation(props.size, Size, 'size');
256
+ handleEnumValidation(props.state, InputState, 'state');
257
+ });
156
258
  </script>
157
259
 
158
260
  <template>
159
261
  <AntField
160
262
  :label="label"
263
+ :label-for="id"
161
264
  :size="size"
162
265
  :skeleton="skeleton"
163
266
  :description="description"
@@ -185,7 +288,8 @@ function onButtonBlur() {
185
288
  />
186
289
 
187
290
  <AntBaseInput
188
- v-model.number="_modelValue"
291
+ :id="id"
292
+ v-model="_modelValue"
189
293
  v-model:input-ref="_inputRef"
190
294
  :type="BaseInputType.number"
191
295
  :grouped="indicators ? Grouped.center : Grouped.none"
@@ -193,6 +297,7 @@ function onButtonBlur() {
193
297
  :state="state"
194
298
  :size="size"
195
299
  :skeleton="skeleton"
300
+ :step="steps"
196
301
  :min="min"
197
302
  :max="max"
198
303
  :disabled="disabled"
@@ -200,7 +305,9 @@ function onButtonBlur() {
200
305
  :placeholder="placeholder || label"
201
306
  :show-icon="false"
202
307
  v-bind="$attrs"
203
- @validate="val => $emit('validate', val)"
308
+ @focus="onInputFocus"
309
+ @blur="onButtonBlur"
310
+ @keydown="onKeyDown"
204
311
  />
205
312
 
206
313
  <AntButton
@@ -61,6 +61,7 @@ const props = withDefaults(defineProps<{
61
61
  inputRef?: null | HTMLInputElement;
62
62
  min?: string | number;
63
63
  max?: string | number;
64
+ step?: string | number;
64
65
  }>(), {
65
66
  state: InputState.base,
66
67
  disabled: false,
@@ -73,6 +74,7 @@ const props = withDefaults(defineProps<{
73
74
  default: false,
74
75
  nullable: false,
75
76
  inputRef: null,
77
+ step: 1,
76
78
  });
77
79
  const slot = useSlots();
78
80
  const hasInputState = computed(() => props.skeleton || props.disabled);
@@ -161,13 +163,26 @@ const icon = computed(() => icons[props.state]);
161
163
  const _modelValue = computed<string | number | null>({
162
164
  get: () => props.modelValue,
163
165
  set: (val: string | number | null) => {
164
- if (props.type === BaseInputType.number && typeof val !== 'number') {
165
- return emit('update:modelValue', null);
166
+ if (props.type === BaseInputType.number) {
167
+ if (val === '' || val === null || val === undefined) {
168
+ emit('update:modelValue', null);
169
+
170
+ return;
171
+ }
172
+
173
+ const num = Number(val);
174
+
175
+ if (!isNaN(num)) {
176
+ emit('update:modelValue', num);
177
+ }
178
+
179
+ return;
166
180
  }
167
181
 
168
182
  emit('update:modelValue', val);
169
183
  },
170
184
  });
185
+
171
186
  const inputIconSize = computed(() => {
172
187
  if (props.size === Size.xs || props.size === Size.xs2) {
173
188
  return IconSize.xs;
@@ -270,6 +285,7 @@ function onClickClearIcon() {
270
285
  :min="min"
271
286
  :max="max"
272
287
  title=""
288
+ :step="step"
273
289
  v-bind="$attrs"
274
290
  :data-e2e-state="state"
275
291
  @blur="onBlur"
@@ -4,5 +4,8 @@ declare const meta: Meta<typeof AntNumberInput>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof AntNumberInput>;
6
6
  export declare const Docs: Story;
7
+ export declare const SelectAllOnFocus: Story;
8
+ export declare const PrecisionAndSteps: Story;
9
+ export declare const Limits: Story;
7
10
  export declare const WithIndicators: Story;
8
11
  export declare const Summary: Story;
@@ -3,13 +3,14 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- module.exports = exports.WithIndicators = exports.Summary = exports.Docs = void 0;
6
+ module.exports = exports.WithIndicators = exports.Summary = exports.SelectAllOnFocus = exports.PrecisionAndSteps = exports.Limits = exports.Docs = void 0;
7
7
  var _Size = require("../../../enums/Size.enum");
8
8
  var _AntNumberInput = _interopRequireDefault(require("../AntNumberInput.vue"));
9
9
  var _State = require("../../../enums/State.enum");
10
10
  var _vue = require("vue");
11
11
  var _AntFormGroup = _interopRequireDefault(require("../../forms/AntFormGroup.vue"));
12
12
  var _AntFormGroupLabel = _interopRequireDefault(require("../../forms/AntFormGroupLabel.vue"));
13
+ var _test = require("@storybook/test");
13
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
15
  const meta = {
15
16
  title: "Inputs/Number Input",
@@ -47,11 +48,19 @@ const meta = {
47
48
  }
48
49
  }
49
50
  },
50
- placeholder: {
51
- table: {
52
- defaultValue: {
53
- summary: "this.label"
54
- }
51
+ steps: {
52
+ control: {
53
+ type: "number"
54
+ }
55
+ },
56
+ min: {
57
+ control: {
58
+ type: "number"
59
+ }
60
+ },
61
+ max: {
62
+ control: {
63
+ type: "number"
55
64
  }
56
65
  }
57
66
  }
@@ -67,20 +76,17 @@ const Docs = exports.Docs = {
67
76
  args
68
77
  };
69
78
  },
70
- template: `
71
- <AntNumberInput
72
- v-bind="args"
73
- v-model="args.modelValue"
74
- />`
79
+ template: '<AntNumberInput v-bind="args" v-model="args.modelValue" />'
75
80
  }),
76
81
  args: {
77
82
  modelValue: null,
78
83
  steps: 1,
79
- label: "Label",
80
- description: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
84
+ label: "Standard Number Input",
85
+ description: "Basic usage with manual entry or indicators",
86
+ onValidate: (0, _test.fn)()
81
87
  }
82
88
  };
83
- const WithIndicators = exports.WithIndicators = {
89
+ const SelectAllOnFocus = exports.SelectAllOnFocus = {
84
90
  render: args => ({
85
91
  components: {
86
92
  AntNumberInput: _AntNumberInput.default,
@@ -88,19 +94,112 @@ const WithIndicators = exports.WithIndicators = {
88
94
  AntFormGroupLabel: _AntFormGroupLabel.default
89
95
  },
90
96
  setup() {
97
+ const val = (0, _vue.ref)(999.99);
91
98
  return {
92
- args
99
+ args,
100
+ val
93
101
  };
94
102
  },
95
103
  template: `
96
- <AntFormGroup>
97
- <AntFormGroup direction="column">
98
- <AntNumberInput v-bind="args" v-model="args.modelValue" label="Label"
99
- description="Lorem ipsum dolor sit amet"/>
100
- <AntNumberInput v-bind="args" v-model="args.modelValue" label="Label"
101
- description="Lorem ipsum dolor sit amet" :steps="0.0001"/>
104
+ <AntFormGroup class="w-80">
105
+ <AntFormGroupLabel>Select All on Focus</AntFormGroupLabel>
106
+ <AntNumberInput
107
+ v-bind="args"
108
+ v-model="val"
109
+ :selectAllOnFocus="true"
110
+ label="Price"
111
+ description="Click to select the entire number for quick replacement"
112
+ />
113
+ </AntFormGroup>
114
+ `
115
+ })
116
+ };
117
+ const PrecisionAndSteps = exports.PrecisionAndSteps = {
118
+ render: args => ({
119
+ components: {
120
+ AntNumberInput: _AntNumberInput.default,
121
+ AntFormGroup: _AntFormGroup.default,
122
+ AntFormGroupLabel: _AntFormGroupLabel.default
123
+ },
124
+ setup() {
125
+ const intVal = (0, _vue.ref)(null);
126
+ const floatVal = (0, _vue.ref)(0.5);
127
+ return {
128
+ args,
129
+ intVal,
130
+ floatVal
131
+ };
132
+ },
133
+ template: `
134
+ <AntFormGroup direction="row">
135
+ <AntFormGroup>
136
+ <AntFormGroupLabel>Integer (Step 1)</AntFormGroupLabel>
137
+ <AntNumberInput v-bind="args" :steps="1" v-model="intVal" />
138
+ </AntFormGroup>
139
+
140
+ <AntFormGroup>
141
+ <AntFormGroupLabel>Currency Style (Step 0.01)</AntFormGroupLabel>
142
+ <AntNumberInput v-bind="args" :steps="0.01" v-model="floatVal" indicators />
143
+ </AntFormGroup>
144
+
145
+ <AntFormGroup>
146
+ <AntFormGroupLabel>High Precision (Step 0.0005)</AntFormGroupLabel>
147
+ <AntNumberInput v-bind="args" :steps="0.0005" v-model="floatVal" indicators />
102
148
  </AntFormGroup>
103
149
  </AntFormGroup>`
150
+ })
151
+ };
152
+ const Limits = exports.Limits = {
153
+ render: args => ({
154
+ components: {
155
+ AntNumberInput: _AntNumberInput.default,
156
+ AntFormGroup: _AntFormGroup.default,
157
+ AntFormGroupLabel: _AntFormGroupLabel.default
158
+ },
159
+ setup() {
160
+ const limitedVal = (0, _vue.ref)(5);
161
+ return {
162
+ args,
163
+ limitedVal
164
+ };
165
+ },
166
+ template: `
167
+ <AntFormGroup class="w-96">
168
+ <AntFormGroupLabel>Min: {{ args.min }} | Max: {{ args.max }}</AntFormGroupLabel>
169
+ <AntNumberInput
170
+ v-bind="args"
171
+ v-model="limitedVal"
172
+ label="Try to exceed limits"
173
+ />
174
+ </AntFormGroup>`
175
+ }),
176
+ args: {
177
+ min: 0,
178
+ max: 10,
179
+ indicators: true,
180
+ limiter: true
181
+ }
182
+ };
183
+ const WithIndicators = exports.WithIndicators = {
184
+ render: args => ({
185
+ components: {
186
+ AntNumberInput: _AntNumberInput.default,
187
+ AntFormGroup: _AntFormGroup.default
188
+ },
189
+ setup() {
190
+ const val1 = (0, _vue.ref)(null);
191
+ const val2 = (0, _vue.ref)(null);
192
+ return {
193
+ args,
194
+ val1,
195
+ val2
196
+ };
197
+ },
198
+ template: `
199
+ <AntFormGroup direction="column">
200
+ <AntNumberInput v-bind="args" v-model="val1" label="Step 1" :steps="1"/>
201
+ <AntNumberInput v-bind="args" v-model="val2" label="Step 0.0001" :steps="0.0001"/>
202
+ </AntFormGroup>`
104
203
  }),
105
204
  args: {
106
205
  ...Docs.args,
@@ -10,6 +10,9 @@ import {
10
10
  } from "vue";
11
11
  import AntFormGroup from "../../forms/AntFormGroup.vue";
12
12
  import AntFormGroupLabel from "../../forms/AntFormGroupLabel.vue";
13
+ import {
14
+ fn
15
+ } from "@storybook/test";
13
16
  const meta = {
14
17
  title: "Inputs/Number Input",
15
18
  component: AntNumberInput,
@@ -46,11 +49,19 @@ const meta = {
46
49
  }
47
50
  }
48
51
  },
49
- placeholder: {
50
- table: {
51
- defaultValue: {
52
- summary: "this.label"
53
- }
52
+ steps: {
53
+ control: {
54
+ type: "number"
55
+ }
56
+ },
57
+ min: {
58
+ control: {
59
+ type: "number"
60
+ }
61
+ },
62
+ max: {
63
+ control: {
64
+ type: "number"
54
65
  }
55
66
  }
56
67
  }
@@ -66,20 +77,17 @@ export const Docs = {
66
77
  args
67
78
  };
68
79
  },
69
- template: `
70
- <AntNumberInput
71
- v-bind="args"
72
- v-model="args.modelValue"
73
- />`
80
+ template: '<AntNumberInput v-bind="args" v-model="args.modelValue" />'
74
81
  }),
75
82
  args: {
76
83
  modelValue: null,
77
84
  steps: 1,
78
- label: "Label",
79
- description: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
85
+ label: "Standard Number Input",
86
+ description: "Basic usage with manual entry or indicators",
87
+ onValidate: fn()
80
88
  }
81
89
  };
82
- export const WithIndicators = {
90
+ export const SelectAllOnFocus = {
83
91
  render: (args) => ({
84
92
  components: {
85
93
  AntNumberInput,
@@ -87,18 +95,111 @@ export const WithIndicators = {
87
95
  AntFormGroupLabel
88
96
  },
89
97
  setup() {
98
+ const val = ref(999.99);
90
99
  return {
91
- args
100
+ args,
101
+ val
92
102
  };
93
103
  },
94
104
  template: `
95
- <AntFormGroup>
96
- <AntFormGroup direction="column">
97
- <AntNumberInput v-bind="args" v-model="args.modelValue" label="Label"
98
- description="Lorem ipsum dolor sit amet"/>
99
- <AntNumberInput v-bind="args" v-model="args.modelValue" label="Label"
100
- description="Lorem ipsum dolor sit amet" :steps="0.0001"/>
105
+ <AntFormGroup class="w-80">
106
+ <AntFormGroupLabel>Select All on Focus</AntFormGroupLabel>
107
+ <AntNumberInput
108
+ v-bind="args"
109
+ v-model="val"
110
+ :selectAllOnFocus="true"
111
+ label="Price"
112
+ description="Click to select the entire number for quick replacement"
113
+ />
114
+ </AntFormGroup>
115
+ `
116
+ })
117
+ };
118
+ export const PrecisionAndSteps = {
119
+ render: (args) => ({
120
+ components: {
121
+ AntNumberInput,
122
+ AntFormGroup,
123
+ AntFormGroupLabel
124
+ },
125
+ setup() {
126
+ const intVal = ref(null);
127
+ const floatVal = ref(0.5);
128
+ return {
129
+ args,
130
+ intVal,
131
+ floatVal
132
+ };
133
+ },
134
+ template: `
135
+ <AntFormGroup direction="row">
136
+ <AntFormGroup>
137
+ <AntFormGroupLabel>Integer (Step 1)</AntFormGroupLabel>
138
+ <AntNumberInput v-bind="args" :steps="1" v-model="intVal" />
139
+ </AntFormGroup>
140
+
141
+ <AntFormGroup>
142
+ <AntFormGroupLabel>Currency Style (Step 0.01)</AntFormGroupLabel>
143
+ <AntNumberInput v-bind="args" :steps="0.01" v-model="floatVal" indicators />
101
144
  </AntFormGroup>
145
+
146
+ <AntFormGroup>
147
+ <AntFormGroupLabel>High Precision (Step 0.0005)</AntFormGroupLabel>
148
+ <AntNumberInput v-bind="args" :steps="0.0005" v-model="floatVal" indicators />
149
+ </AntFormGroup>
150
+ </AntFormGroup>`
151
+ })
152
+ };
153
+ export const Limits = {
154
+ render: (args) => ({
155
+ components: {
156
+ AntNumberInput,
157
+ AntFormGroup,
158
+ AntFormGroupLabel
159
+ },
160
+ setup() {
161
+ const limitedVal = ref(5);
162
+ return {
163
+ args,
164
+ limitedVal
165
+ };
166
+ },
167
+ template: `
168
+ <AntFormGroup class="w-96">
169
+ <AntFormGroupLabel>Min: {{ args.min }} | Max: {{ args.max }}</AntFormGroupLabel>
170
+ <AntNumberInput
171
+ v-bind="args"
172
+ v-model="limitedVal"
173
+ label="Try to exceed limits"
174
+ />
175
+ </AntFormGroup>`
176
+ }),
177
+ args: {
178
+ min: 0,
179
+ max: 10,
180
+ indicators: true,
181
+ limiter: true
182
+ }
183
+ };
184
+ export const WithIndicators = {
185
+ render: (args) => ({
186
+ components: {
187
+ AntNumberInput,
188
+ AntFormGroup
189
+ },
190
+ setup() {
191
+ const val1 = ref(null);
192
+ const val2 = ref(null);
193
+ return {
194
+ args,
195
+ val1,
196
+ val2
197
+ };
198
+ },
199
+ template: `
200
+ <AntFormGroup direction="column">
201
+ <AntNumberInput v-bind="args" v-model="val1" label="Step 1" :steps="1"/>
202
+ <AntNumberInput v-bind="args" v-model="val2" label="Step 0.0001" :steps="0.0001"/>
102
203
  </AntFormGroup>`
103
204
  }),
104
205
  args: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antify/ui",
3
- "version": "4.1.32",
3
+ "version": "4.1.34",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {