@ouestfrance/sipa-bms-ui 8.22.2 → 8.23.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 (83) hide show
  1. package/dist/components/button/BmsButton.vue.d.ts +1 -1
  2. package/dist/components/button/BmsIconButton.vue.d.ts +1 -1
  3. package/dist/components/button/BmsToggleIcon.vue.d.ts +24 -0
  4. package/dist/components/button/UiButton.vue.d.ts +1 -1
  5. package/dist/components/form/BmsInputText.vue.d.ts +1 -1
  6. package/dist/components/form/BmsSearch.vue.d.ts +3 -3
  7. package/dist/components/form/BmsSelect.vue.d.ts +1 -1
  8. package/dist/components/form/RawSelect.vue.d.ts +1 -1
  9. package/dist/components/layout/BmsHeaderTitle.vue.d.ts +1 -1
  10. package/dist/components/navigation/BmsBreadcrumb.vue.d.ts +1 -1
  11. package/dist/components/navigation/BmsShortLinkMenu.vue.d.ts +2 -2
  12. package/dist/components/navigation/UiTenantSwitcher.vue.d.ts +3 -3
  13. package/dist/components/table/BmsPagination.vue.d.ts +4 -2
  14. package/dist/components/table/BmsServerTable.vue.d.ts +3 -3
  15. package/dist/components/table/BmsTable.vue.d.ts +3 -3
  16. package/dist/components/table/BmsTableFilters.vue.d.ts +5 -3
  17. package/dist/components/table/UiBmsTable.vue.d.ts +3 -3
  18. package/dist/components/table/UiFilterButton.vue.d.ts +2 -0
  19. package/dist/index.d.ts +2 -1
  20. package/dist/models/table.model.d.ts +5 -0
  21. package/dist/plugins/field/FieldComponent.vue.d.ts +1 -1
  22. package/dist/plugins/router-history/router-history.composable.d.ts +1 -1
  23. package/dist/showroom/pages/table.vue.d.ts +2 -0
  24. package/dist/sipa-bms-ui.css +167 -103
  25. package/dist/sipa-bms-ui.es.js +3838 -3301
  26. package/dist/sipa-bms-ui.es.js.map +1 -1
  27. package/dist/sipa-bms-ui.umd.js +3842 -3303
  28. package/dist/sipa-bms-ui.umd.js.map +1 -1
  29. package/package.json +19 -19
  30. package/src/components/button/BmsButton.stories.js +142 -3
  31. package/src/components/button/BmsToggleIcon.stories.js +145 -0
  32. package/src/components/button/BmsToggleIcon.vue +108 -0
  33. package/src/components/form/BmsChip.stories.js +104 -2
  34. package/src/components/form/BmsInputCheckboxCaptionGroup.stories.js +157 -2
  35. package/src/components/form/BmsInputCheckboxGroup.stories.js +119 -2
  36. package/src/components/form/BmsInputCode.stories.js +109 -2
  37. package/src/components/form/BmsInputFile.stories.js +110 -2
  38. package/src/components/form/BmsInputNumber.stories.js +12 -2
  39. package/src/components/form/BmsInputNumber.vue +2 -1
  40. package/src/components/form/BmsInputRadioCaptionGroup.stories.js +138 -2
  41. package/src/components/form/BmsInputRadioGroup.stories.js +120 -2
  42. package/src/components/form/BmsInputText.stories.js +278 -1
  43. package/src/components/form/BmsInputText.vue +2 -0
  44. package/src/components/form/BmsMultiSelect.vue +3 -1
  45. package/src/components/form/BmsSearch.stories.js +89 -2
  46. package/src/components/form/BmsSelect.stories.js +220 -2
  47. package/src/components/form/BmsSelect.vue +5 -3
  48. package/src/components/form/BmsTag.stories.js +119 -3
  49. package/src/components/form/BmsTextArea.stories.js +146 -2
  50. package/src/components/form/RawAutocomplete.vue +3 -1
  51. package/src/components/layout/BmsFloatingWindow.vue +12 -1
  52. package/src/components/layout/BmsForm.stories.js +216 -0
  53. package/src/components/layout/BmsHeaderTitle.stories.js +136 -1
  54. package/src/components/layout/BmsSplitWindow.vue +1 -1
  55. package/src/components/table/BmsPagination.vue +3 -0
  56. package/src/components/table/BmsServerTable.stories.js +59 -3
  57. package/src/components/table/BmsServerTable.vue +9 -2
  58. package/src/components/table/BmsTable.stories.js +312 -2
  59. package/src/components/table/BmsTable.vue +14 -3
  60. package/src/components/table/BmsTableFilters.vue +15 -5
  61. package/src/components/table/UiBmsTable.stories.js +3 -0
  62. package/src/components/table/UiBmsTable.vue +14 -5
  63. package/src/components/table/UiFilterButton.vue +6 -1
  64. package/src/documentation/button/secondaryButton.mdx +114 -3
  65. package/src/documentation/checkboxCaptionGroup.mdx +99 -0
  66. package/src/documentation/checkboxGroup.mdx +99 -0
  67. package/src/documentation/chip.mdx +85 -11
  68. package/src/documentation/inputCode.mdx +97 -0
  69. package/src/documentation/inputFile.mdx +90 -13
  70. package/src/documentation/inputText.mdx +183 -0
  71. package/src/documentation/layout/form.mdx +74 -0
  72. package/src/documentation/layout/headerTitle.mdx +124 -0
  73. package/src/documentation/layout/table.mdx +111 -0
  74. package/src/documentation/radioCaptionGroup.mdx +86 -19
  75. package/src/documentation/radioGroup.mdx +85 -18
  76. package/src/documentation/search.mdx +85 -13
  77. package/src/documentation/select.mdx +137 -16
  78. package/src/documentation/tag.mdx +91 -11
  79. package/src/documentation/textArea.mdx +126 -13
  80. package/src/index.ts +3 -0
  81. package/src/models/table.model.ts +6 -0
  82. package/src/showroom/pages/floating-window.vue +36 -0
  83. package/src/documentation/fields_text.mdx +0 -31
@@ -1,17 +1,18 @@
1
1
  import BmsInputRadioCaptionGroup from '@/components/form/BmsInputRadioCaptionGroup.vue';
2
2
  import BmsInputRadioCaption from '@/components/form/BmsInputRadioCaption.vue';
3
3
  import { StatusType } from '@/models/status-type.model';
4
+ import { ref } from 'vue';
4
5
 
5
6
  import template from '@/documentation/template_field_dependency.mdx';
6
7
 
7
8
  export default {
9
+ title: 'Composants/form/InputRadioCaptionGroup',
10
+ component: BmsInputRadioCaptionGroup,
8
11
  parameters: {
9
12
  docs: {
10
13
  page: template,
11
14
  },
12
15
  },
13
- title: 'Composants/form/InputRadioCaptionGroup',
14
- component: BmsInputRadioCaptionGroup,
15
16
  };
16
17
 
17
18
  const Template = (args) => ({
@@ -164,3 +165,138 @@ Slot.args = {
164
165
  label: 'This is a field label',
165
166
  slot: true,
166
167
  };
168
+
169
+ // Simple template for documentation
170
+ const SimpleTemplate = (args) => ({
171
+ setup() {
172
+ const modelValue = ref(args.modelValue || '');
173
+ return { args, modelValue };
174
+ },
175
+ components: {
176
+ BmsInputRadioCaptionGroup,
177
+ },
178
+ template: `
179
+ <BmsInputRadioCaptionGroup v-bind="args" v-model="modelValue" />
180
+ `,
181
+ });
182
+
183
+ // Playground with default values for documentation
184
+ export const PlaygroundRadioCaptionGroup = SimpleTemplate.bind({});
185
+ PlaygroundRadioCaptionGroup.parameters = { chromatic: { disable: true } };
186
+ PlaygroundRadioCaptionGroup.args = {
187
+ label: 'Payment method',
188
+ modelValue: '',
189
+ options: [
190
+ {
191
+ value: 'credit',
192
+ label: 'Credit Card',
193
+ captions: ['Visa, Mastercard, Amex'],
194
+ },
195
+ { value: 'paypal', label: 'PayPal', captions: ['Pay with PayPal account'] },
196
+ {
197
+ value: 'bank',
198
+ label: 'Bank Transfer',
199
+ captions: ['Direct bank transfer'],
200
+ },
201
+ ],
202
+ };
203
+
204
+ // Do: Radio caption group with clear labels
205
+ export const DoWithClearLabels = SimpleTemplate.bind({});
206
+ DoWithClearLabels.parameters = { chromatic: { disable: true } };
207
+ DoWithClearLabels.args = {
208
+ label: 'Subscription plan',
209
+ modelValue: '',
210
+ options: [
211
+ { value: 'basic', label: 'Basic', captions: ['$9/month'] },
212
+ { value: 'pro', label: 'Pro', captions: ['$29/month'] },
213
+ { value: 'enterprise', label: 'Enterprise', captions: ['Custom pricing'] },
214
+ ],
215
+ };
216
+
217
+ // Do: Radio caption group with helpful captions
218
+ export const DoWithHelpfulCaptions = SimpleTemplate.bind({});
219
+ DoWithHelpfulCaptions.parameters = { chromatic: { disable: true } };
220
+ DoWithHelpfulCaptions.args = {
221
+ label: 'Delivery option',
222
+ modelValue: '',
223
+ options: [
224
+ { value: 'standard', label: 'Standard', captions: ['5-7 business days'] },
225
+ { value: 'express', label: 'Express', captions: ['2-3 business days'] },
226
+ { value: 'overnight', label: 'Overnight', captions: ['Next business day'] },
227
+ ],
228
+ };
229
+
230
+ // Do: Radio caption group with error feedback
231
+ export const DoWithErrorFeedback = SimpleTemplate.bind({});
232
+ DoWithErrorFeedback.parameters = { chromatic: { disable: true } };
233
+ DoWithErrorFeedback.args = {
234
+ label: 'Payment method',
235
+ modelValue: '',
236
+ errors: ['Please select a payment method'],
237
+ options: [
238
+ { value: 'credit', label: 'Credit Card', captions: ['Visa, Mastercard'] },
239
+ { value: 'paypal', label: 'PayPal', captions: ['Pay with PayPal'] },
240
+ ],
241
+ };
242
+
243
+ // Don't: Missing labels
244
+ export const DontNoLabel = SimpleTemplate.bind({});
245
+ DontNoLabel.parameters = { chromatic: { disable: true } };
246
+ DontNoLabel.args = {
247
+ modelValue: '',
248
+ options: [
249
+ { value: 'option1', label: 'Option 1', captions: ['Description'] },
250
+ { value: 'option2', label: 'Option 2', captions: ['Description'] },
251
+ ],
252
+ };
253
+
254
+ export const DoWithLabel = SimpleTemplate.bind({});
255
+ DoWithLabel.parameters = { chromatic: { disable: true } };
256
+ DoWithLabel.args = {
257
+ label: 'Choose an option',
258
+ modelValue: '',
259
+ options: [
260
+ { value: 'option1', label: 'Option 1', captions: ['Description'] },
261
+ { value: 'option2', label: 'Option 2', captions: ['Description'] },
262
+ ],
263
+ };
264
+
265
+ // Don't: No captions when needed
266
+ export const DontNoCaptions = SimpleTemplate.bind({});
267
+ DontNoCaptions.parameters = { chromatic: { disable: true } };
268
+ DontNoCaptions.args = {
269
+ label: 'Subscription plan',
270
+ modelValue: '',
271
+ options: [
272
+ { value: 'basic', label: 'Basic' },
273
+ { value: 'pro', label: 'Pro' },
274
+ { value: 'enterprise', label: 'Enterprise' },
275
+ ],
276
+ };
277
+
278
+ // Do: Radio caption group in column layout
279
+ export const DoWithColumnLayout = SimpleTemplate.bind({});
280
+ DoWithColumnLayout.parameters = { chromatic: { disable: true } };
281
+ DoWithColumnLayout.args = {
282
+ label: 'Delivery option',
283
+ modelValue: '',
284
+ align: 'column',
285
+ options: [
286
+ {
287
+ value: 'standard',
288
+ label: 'Standard Delivery',
289
+ captions: ['5-7 business days - Free'],
290
+ },
291
+ {
292
+ value: 'express',
293
+ label: 'Express Delivery',
294
+ captions: ['2-3 business days - $10'],
295
+ },
296
+ {
297
+ value: 'overnight',
298
+ label: 'Overnight Delivery',
299
+ captions: ['Next business day - $25'],
300
+ },
301
+ ],
302
+ };
@@ -1,17 +1,18 @@
1
1
  import BmsInputRadioGroup from '@/components/form/BmsInputRadioGroup.vue';
2
2
  import BmsInputRadio from '@/components/form/BmsInputRadio.vue';
3
3
  import { StatusType } from '@/models/status-type.model';
4
+ import { ref } from 'vue';
4
5
 
5
6
  import template from '@/documentation/template_field_dependency.mdx';
6
7
 
7
8
  export default {
9
+ title: 'Composants/form/InputRadioGroup',
10
+ component: BmsInputRadioGroup,
8
11
  parameters: {
9
12
  docs: {
10
13
  page: template,
11
14
  },
12
15
  },
13
- title: 'Composants/form/InputRadioGroup',
14
- component: BmsInputRadioGroup,
15
16
  };
16
17
 
17
18
  const Template = (args) => ({
@@ -118,3 +119,120 @@ Slot.args = {
118
119
  label: 'This is a field label',
119
120
  slot: true,
120
121
  };
122
+
123
+ // Simple template for documentation
124
+ const SimpleTemplate = (args) => ({
125
+ setup() {
126
+ const modelValue = ref(args.modelValue || '');
127
+ return { args, modelValue };
128
+ },
129
+ components: {
130
+ BmsInputRadioGroup,
131
+ },
132
+ template: `
133
+ <BmsInputRadioGroup v-bind="args" v-model="modelValue" />
134
+ `,
135
+ });
136
+
137
+ // Playground with default values for documentation
138
+ export const PlaygroundRadioGroup = SimpleTemplate.bind({});
139
+ PlaygroundRadioGroup.parameters = { chromatic: { disable: true } };
140
+ PlaygroundRadioGroup.args = {
141
+ label: 'Gender',
142
+ modelValue: '',
143
+ values: [
144
+ { value: 'male', label: 'Male' },
145
+ { value: 'female', label: 'Female' },
146
+ { value: 'other', label: 'Other' },
147
+ ],
148
+ };
149
+
150
+ // Do: Radio group with clear labels
151
+ export const DoWithClearLabels = SimpleTemplate.bind({});
152
+ DoWithClearLabels.parameters = { chromatic: { disable: true } };
153
+ DoWithClearLabels.args = {
154
+ label: 'Notification preference',
155
+ modelValue: '',
156
+ values: [
157
+ { value: 'email', label: 'Email' },
158
+ { value: 'sms', label: 'SMS' },
159
+ { value: 'push', label: 'Push notifications' },
160
+ ],
161
+ };
162
+
163
+ // Do: Radio group with caption
164
+ export const DoWithCaption = SimpleTemplate.bind({});
165
+ DoWithCaption.parameters = { chromatic: { disable: true } };
166
+ DoWithCaption.args = {
167
+ label: 'Account type',
168
+ modelValue: '',
169
+ captions: ['Select the type of account you want to create'],
170
+ values: [
171
+ { value: 'personal', label: 'Personal' },
172
+ { value: 'business', label: 'Business' },
173
+ ],
174
+ };
175
+
176
+ // Do: Radio group with error feedback
177
+ export const DoWithErrorFeedback = SimpleTemplate.bind({});
178
+ DoWithErrorFeedback.parameters = { chromatic: { disable: true } };
179
+ DoWithErrorFeedback.args = {
180
+ label: 'Gender',
181
+ modelValue: '',
182
+ errors: ['Please select a gender'],
183
+ values: [
184
+ { value: 'male', label: 'Male' },
185
+ { value: 'female', label: 'Female' },
186
+ { value: 'other', label: 'Other' },
187
+ ],
188
+ };
189
+
190
+ // Don't: Missing labels
191
+ export const DontNoLabel = SimpleTemplate.bind({});
192
+ DontNoLabel.parameters = { chromatic: { disable: true } };
193
+ DontNoLabel.args = {
194
+ modelValue: '',
195
+ values: [
196
+ { value: 'option1', label: 'Option 1' },
197
+ { value: 'option2', label: 'Option 2' },
198
+ ],
199
+ };
200
+
201
+ export const DoWithLabel = SimpleTemplate.bind({});
202
+ DoWithLabel.parameters = { chromatic: { disable: true } };
203
+ DoWithLabel.args = {
204
+ label: 'Choose an option',
205
+ modelValue: '',
206
+ values: [
207
+ { value: 'option1', label: 'Option 1' },
208
+ { value: 'option2', label: 'Option 2' },
209
+ ],
210
+ };
211
+
212
+ // Don't: No error feedback
213
+ export const DontNoErrorFeedback = SimpleTemplate.bind({});
214
+ DontNoErrorFeedback.parameters = { chromatic: { disable: true } };
215
+ DontNoErrorFeedback.args = {
216
+ label: 'Gender',
217
+ modelValue: '',
218
+ values: [
219
+ { value: 'male', label: 'Male' },
220
+ { value: 'female', label: 'Female' },
221
+ ],
222
+ };
223
+
224
+ // Do: Radio group in column layout
225
+ export const DoWithColumnLayout = SimpleTemplate.bind({});
226
+ DoWithColumnLayout.parameters = { chromatic: { disable: true } };
227
+ DoWithColumnLayout.args = {
228
+ label: 'Notification preference',
229
+ modelValue: '',
230
+ align: 'column',
231
+ captions: ['Choose how you want to receive notifications'],
232
+ values: [
233
+ { value: 'email', label: 'Email notifications' },
234
+ { value: 'sms', label: 'SMS notifications' },
235
+ { value: 'push', label: 'Push notifications' },
236
+ { value: 'none', label: 'No notifications' },
237
+ ],
238
+ };
@@ -1,6 +1,6 @@
1
1
  import BmsInputText from '@/components/form/BmsInputText.vue';
2
2
  import { within } from 'storybook/test';
3
- import { BookOpen, CloudLightning } from 'lucide-vue-next';
3
+ import { BookOpen, CloudLightning, Mail, Eye } from 'lucide-vue-next';
4
4
  import template from '@/documentation/template_field_dependency.mdx';
5
5
  import { ref } from 'vue';
6
6
 
@@ -85,6 +85,15 @@ WithLimitEqual.args = {
85
85
  maxlength: 16,
86
86
  };
87
87
 
88
+ export const WithLimitAndEmptyValue = Template.bind({});
89
+ WithLimitAndEmptyValue.args = {
90
+ label: 'My label',
91
+ modelValue: null,
92
+ modelValueSmall: undefined,
93
+ maxlength: 15,
94
+ minlength: 1,
95
+ };
96
+
88
97
  export const WithLimitExceeded = Template.bind({});
89
98
  WithLimitExceeded.args = {
90
99
  label: 'My label',
@@ -114,3 +123,271 @@ export const WithFocusState = {
114
123
  await canvas.getByRole('input').focus();
115
124
  },
116
125
  };
126
+
127
+ // Simple template for documentation (without small variant)
128
+ const SimpleTemplate = (args) => ({
129
+ setup() {
130
+ const modelValue = ref(args.modelValue || '');
131
+ return { args, modelValue };
132
+ },
133
+ components: {
134
+ BmsInputText,
135
+ BookOpen,
136
+ CloudLightning,
137
+ },
138
+ template: `
139
+ <BmsInputText v-bind="args" v-model="modelValue">
140
+ <template v-if="args.iconStart" #icon-start><BookOpen/></template>
141
+ <template v-if="args.iconEnd" #icon-end><CloudLightning/></template>
142
+ </BmsInputText>
143
+ `,
144
+ });
145
+
146
+ // Playground with default values for documentation
147
+ export const PlaygroundInputText = SimpleTemplate.bind({});
148
+ PlaygroundInputText.parameters = { chromatic: { disable: true } };
149
+ PlaygroundInputText.args = {
150
+ label: 'Email address',
151
+ placeholder: 'example@email.com',
152
+ };
153
+
154
+ // Do: Simple input with label
155
+ export const DoWithLabel = SimpleTemplate.bind({});
156
+ DoWithLabel.parameters = { chromatic: { disable: true } };
157
+ DoWithLabel.args = {
158
+ label: 'Full name',
159
+ placeholder: 'John Doe',
160
+ };
161
+
162
+ // Do: Input with placeholder
163
+ export const DoWithPlaceholder = SimpleTemplate.bind({});
164
+ DoWithPlaceholder.parameters = { chromatic: { disable: true } };
165
+ DoWithPlaceholder.args = {
166
+ label: 'Email address',
167
+ placeholder: 'example@email.com',
168
+ };
169
+
170
+ // Do: Input with caption
171
+ export const DoWithCaption = SimpleTemplate.bind({});
172
+ DoWithCaption.parameters = { chromatic: { disable: true } };
173
+ DoWithCaption.args = {
174
+ label: 'Password',
175
+ placeholder: 'Enter your password',
176
+ captions: ['Must be at least 8 characters'],
177
+ };
178
+
179
+ // Do: Input with icon at start
180
+ export const DoWithIconStart = () => ({
181
+ components: { BmsInputText, Mail },
182
+ setup() {
183
+ const value = ref('');
184
+ return { value };
185
+ },
186
+ template: `
187
+ <BmsInputText
188
+ label="Email"
189
+ v-model="value"
190
+ placeholder="example@email.com"
191
+ >
192
+ <template #icon-start><Mail /></template>
193
+ </BmsInputText>
194
+ `,
195
+ });
196
+ DoWithIconStart.parameters = { chromatic: { disable: true } };
197
+
198
+ // Do: Input with icon at end
199
+ export const DoWithIconEnd = () => ({
200
+ components: { BmsInputText, Eye },
201
+ setup() {
202
+ const value = ref('');
203
+ return { value };
204
+ },
205
+ template: `
206
+ <BmsInputText
207
+ label="Password"
208
+ v-model="value"
209
+ placeholder="Enter your password"
210
+ >
211
+ <template #icon-end><Eye /></template>
212
+ </BmsInputText>
213
+ `,
214
+ });
215
+ DoWithIconEnd.parameters = { chromatic: { disable: true } };
216
+
217
+ // Do: Input with both icons
218
+ export const DoWithIcons = () => ({
219
+ components: { BmsInputText, Mail, Eye },
220
+ setup() {
221
+ const value = ref('');
222
+ return { value };
223
+ },
224
+ template: `
225
+ <BmsInputText
226
+ label="Email"
227
+ v-model="value"
228
+ placeholder="example@email.com"
229
+ >
230
+ <template #icon-start><Mail /></template>
231
+ <template #icon-end><Eye /></template>
232
+ </BmsInputText>
233
+ `,
234
+ });
235
+ DoWithIcons.parameters = { chromatic: { disable: true } };
236
+
237
+ // Do: Disabled state
238
+ export const DoDisabled = SimpleTemplate.bind({});
239
+ DoDisabled.parameters = { chromatic: { disable: true } };
240
+ DoDisabled.args = {
241
+ label: 'Account ID',
242
+ modelValue: 'ACC-12345',
243
+ disabled: true,
244
+ };
245
+
246
+ // Do: Loading state
247
+ export const DoLoading = SimpleTemplate.bind({});
248
+ DoLoading.parameters = { chromatic: { disable: true } };
249
+ DoLoading.args = {
250
+ label: 'Email',
251
+ placeholder: 'Loading...',
252
+ loading: true,
253
+ };
254
+
255
+ // Do: Input with max length
256
+ export const DoWithMaxLength = SimpleTemplate.bind({});
257
+ DoWithMaxLength.parameters = { chromatic: { disable: true } };
258
+ DoWithMaxLength.args = {
259
+ label: 'Username',
260
+ placeholder: 'Enter username',
261
+ maxlength: 20,
262
+ modelValue: 'myusernameiswaytoolong',
263
+ };
264
+
265
+ // Do: Input with min and max length
266
+ export const DoWithMinMaxLength = SimpleTemplate.bind({});
267
+ DoWithMinMaxLength.parameters = { chromatic: { disable: true } };
268
+ DoWithMinMaxLength.args = {
269
+ label: 'Password',
270
+ placeholder: 'Enter password',
271
+ minlength: 8,
272
+ maxlength: 20,
273
+ modelValue: 'pass123',
274
+ };
275
+
276
+ // Don't: Long labels
277
+ export const DontLongLabel = SimpleTemplate.bind({});
278
+ DontLongLabel.parameters = { chromatic: { disable: true } };
279
+ DontLongLabel.args = {
280
+ label:
281
+ 'Please enter your complete full name including first name, middle name if applicable, and last name',
282
+ placeholder: 'Name',
283
+ };
284
+
285
+ export const DoShortLabel = SimpleTemplate.bind({});
286
+ DoShortLabel.parameters = { chromatic: { disable: true } };
287
+ DoShortLabel.args = {
288
+ label: 'Full name',
289
+ placeholder: 'John Doe',
290
+ };
291
+
292
+ // Don't: No label
293
+ export const DontNoLabel = SimpleTemplate.bind({});
294
+ DontNoLabel.parameters = { chromatic: { disable: true } };
295
+ DontNoLabel.args = {
296
+ placeholder: 'Enter your email',
297
+ };
298
+
299
+ // Don't: Generic placeholder
300
+ export const DontGenericPlaceholder = SimpleTemplate.bind({});
301
+ DontGenericPlaceholder.parameters = { chromatic: { disable: true } };
302
+ DontGenericPlaceholder.args = {
303
+ label: 'Email',
304
+ placeholder: 'Enter text here',
305
+ };
306
+
307
+ export const DoSpecificPlaceholder = SimpleTemplate.bind({});
308
+ DoSpecificPlaceholder.parameters = { chromatic: { disable: true } };
309
+ DoSpecificPlaceholder.args = {
310
+ label: 'Email',
311
+ placeholder: 'example@email.com',
312
+ };
313
+
314
+ // Don't: Too many icons
315
+ export const DontTooManyIcons = () => ({
316
+ components: { BmsInputText, Mail, Eye, BookOpen },
317
+ setup() {
318
+ const value = ref('');
319
+ return { value };
320
+ },
321
+ template: `
322
+ <BmsInputText
323
+ label="Email"
324
+ v-model="value"
325
+ placeholder="example@email.com"
326
+ >
327
+ <template #icon-start>
328
+ <Mail />
329
+ <BookOpen />
330
+ </template>
331
+ <template #icon-end>
332
+ <Eye />
333
+ <BookOpen />
334
+ </template>
335
+ </BmsInputText>
336
+ `,
337
+ });
338
+ DontTooManyIcons.parameters = { chromatic: { disable: true } };
339
+
340
+ export const DoOneIcon = () => ({
341
+ components: { BmsInputText, Mail },
342
+ setup() {
343
+ const value = ref('');
344
+ return { value };
345
+ },
346
+ template: `
347
+ <BmsInputText
348
+ label="Email"
349
+ v-model="value"
350
+ placeholder="example@email.com"
351
+ >
352
+ <template #icon-start><Mail /></template>
353
+ </BmsInputText>
354
+ `,
355
+ });
356
+ DoOneIcon.parameters = { chromatic: { disable: true } };
357
+
358
+ // Don't: No error feedback
359
+ export const DontNoErrorFeedback = SimpleTemplate.bind({});
360
+ DontNoErrorFeedback.parameters = { chromatic: { disable: true } };
361
+ DontNoErrorFeedback.args = {
362
+ label: 'Email',
363
+ placeholder: 'email@example.com',
364
+ modelValue: 'invalid-email',
365
+ };
366
+
367
+ export const DoWithErrorFeedback = SimpleTemplate.bind({});
368
+ DoWithErrorFeedback.parameters = { chromatic: { disable: true } };
369
+ DoWithErrorFeedback.args = {
370
+ label: 'Email',
371
+ placeholder: 'email@example.com',
372
+ modelValue: 'invalid-email',
373
+ errors: ['Please enter a valid email address'],
374
+ };
375
+
376
+ // Don't: No caption for complex requirements
377
+ export const DontNoCaption = SimpleTemplate.bind({});
378
+ DontNoCaption.parameters = { chromatic: { disable: true } };
379
+ DontNoCaption.args = {
380
+ label: 'Username',
381
+ placeholder: 'Enter username',
382
+ modelValue: 'JohnDoe',
383
+ errors: ['Error'],
384
+ };
385
+
386
+ export const DoWithHelpfulCaption = SimpleTemplate.bind({});
387
+ DoWithHelpfulCaption.parameters = { chromatic: { disable: true } };
388
+ DoWithHelpfulCaption.args = {
389
+ label: 'Username',
390
+ placeholder: 'Enter username',
391
+ modelValue: 'JohnDoe',
392
+ errors: ['Username is already taken'],
393
+ };
@@ -88,7 +88,9 @@ const onInput = (e: Event) => {
88
88
  const checkLimit = () => {
89
89
  internalErrors.value = [];
90
90
  internalCaptions.value = [];
91
+ const hasValue = props.modelValue !== null && props.modelValue !== undefined;
91
92
  if (
93
+ hasValue &&
92
94
  props.inputType === InputType.TEXT &&
93
95
  typeof props.modelValue === 'string'
94
96
  ) {
@@ -108,7 +108,9 @@ onKeyUp('Tab', closeDatalist);
108
108
  onKeyDown('Backspace', onBackspace);
109
109
 
110
110
  const onSelectClick = () => {
111
- isDatalistOpen.value = !isDatalistOpen.value;
111
+ if (!props.disabled) {
112
+ isDatalistOpen.value = !isDatalistOpen.value;
113
+ }
112
114
  };
113
115
  const onInput = (e: InputEvent) => {
114
116
  emits('input', e);