@simsustech/quasar-components 0.4.8 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @simsustech/quasar-components
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 401bf7b: feat: change DateInput to separate input fields for year, month and day
8
+ - fa4989f: feat: add autocomplete attributes to LoginForm
9
+
3
10
  ## 0.4.8
4
11
 
5
12
  ### Patch Changes
@@ -14,7 +14,7 @@ var define_import_meta_env_default = { BASE_URL: "/", MODE: "production", DEV: f
14
14
  const lang = ref(lang$1);
15
15
  const locales = /* @__PURE__ */ Object.assign({
16
16
  "./en-US.ts": () => Promise.resolve().then(() => enUS),
17
- "./nl.ts": () => import("./nl-ddFMi2cz.js")
17
+ "./nl.ts": () => import("./nl-vB00g7s2.js")
18
18
  });
19
19
  const useLang = () => {
20
20
  return lang;
@@ -1,6 +1,6 @@
1
1
  import { useQuasar, QForm, QInput, QStep, QStepperNavigation, QStepper, QIcon, QBtn, QSlider, QItemSection, QItem, QList, QMenu } from "quasar";
2
2
  import { ref, defineComponent, watch, computed, openBlock, createBlock, unref, mergeProps, withCtx, createVNode, renderSlot, toRef, createCommentVNode, createElementBlock, Fragment, renderList, createTextVNode, toDisplayString } from "vue";
3
- import { _ as _sfc_main$c } from "./QSubmitButton.vue_vue_type_script_setup_true_lang-3DA1OTeA.js";
3
+ import { _ as _sfc_main$c } from "./QSubmitButton.vue_vue_type_script_setup_true_lang-DAnZaTMl.js";
4
4
  const lang$1 = {
5
5
  isoName: "en-US",
6
6
  myAccount: "Account",
@@ -98,7 +98,7 @@ var define_import_meta_env_default = { BASE_URL: "/", MODE: "production", DEV: f
98
98
  const lang = ref(lang$1);
99
99
  const locales = /* @__PURE__ */ Object.assign({
100
100
  "./en-US.ts": () => Promise.resolve().then(() => enUS),
101
- "./nl.ts": () => import("./nl-Y-pHriZy.js")
101
+ "./nl.ts": () => import("./nl-CBxnt0JS.js")
102
102
  });
103
103
  const useLang = () => {
104
104
  return lang;
@@ -1059,7 +1059,8 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
1059
1059
  label: unref(lang2).login.fields.email,
1060
1060
  "bottom-slots": "",
1061
1061
  rules: validations.value["email"],
1062
- "lazy-rules": ""
1062
+ "lazy-rules": "",
1063
+ autcomplete: "email"
1063
1064
  }), null, 16, ["modelValue", "label", "rules"])) : createCommentVNode("", true),
1064
1065
  _ctx.useUsername ? (openBlock(), createBlock(_component_q_input, mergeProps({ key: 1 }, _ctx.input, {
1065
1066
  id: "username",
@@ -1069,7 +1070,8 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
1069
1070
  label: unref(lang2).login.fields.username,
1070
1071
  "bottom-slots": "",
1071
1072
  rules: validations.value["username"],
1072
- "lazy-rules": ""
1073
+ "lazy-rules": "",
1074
+ autocomplete: "username"
1073
1075
  }), null, 16, ["modelValue", "label", "rules"])) : createCommentVNode("", true),
1074
1076
  createVNode(_component_q_input, mergeProps({
1075
1077
  id: "password",
@@ -1082,7 +1084,8 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
1082
1084
  label: unref(lang2).login.fields.password,
1083
1085
  rules: validations.value["password"],
1084
1086
  "lazy-rules": "",
1085
- "bottom-slots": ""
1087
+ "bottom-slots": "",
1088
+ autcomplete: "current-password"
1086
1089
  }), {
1087
1090
  append: withCtx(() => [
1088
1091
  createVNode(_component_q_icon, {
@@ -139,7 +139,7 @@ var define_import_meta_env_default = { BASE_URL: "/", MODE: "production", DEV: f
139
139
  const lang = ref(lang$1);
140
140
  const locales = /* @__PURE__ */ Object.assign({
141
141
  "./en-US.ts": () => Promise.resolve().then(() => enUS),
142
- "./nl.ts": () => import("./nl-w63lODNM.js")
142
+ "./nl.ts": () => import("./nl-iCAs4ELa.js")
143
143
  });
144
144
  const useLang = () => {
145
145
  return lang;
package/dist/flags.js CHANGED
@@ -1,6 +1,4 @@
1
- import { e, n } from "./en-US-Ub0VDpRf.js";
2
- import "vue";
3
- import "quasar";
1
+ import { e, n } from "./en-US-Duo_j_eL.js";
4
2
  export {
5
3
  e as enUs,
6
4
  n as nl
package/dist/form.js CHANGED
@@ -1,5 +1,5 @@
1
- import { ref, defineComponent, useAttrs, withAsyncContext, watch, openBlock, createBlock, unref, mergeProps, normalizeProps, guardReactiveProps, withCtx, createVNode, createTextVNode, toDisplayString, computed, useSlots, renderSlot, createCommentVNode, toRefs, resolveDirective, createElementVNode, withDirectives, createElementBlock, Fragment } from "vue";
2
- import { useQuasar, QSelect, QItem, QItemSection, QItemLabel, QInput, QIcon, QBtn, QDate, QPopupProxy, QEditor } from "quasar";
1
+ import { ref, defineComponent, useAttrs, withAsyncContext, watch, openBlock, createBlock, unref, mergeProps, normalizeProps, guardReactiveProps, withCtx, createVNode, createTextVNode, toDisplayString, computed, useSlots, renderSlot, createCommentVNode, toRefs, resolveDirective, createElementBlock, Fragment, renderList, resolveDynamicComponent, createElementVNode, withDirectives } from "vue";
2
+ import { useQuasar, QSelect, QItem, QItemSection, QItemLabel, QInput, QDate, QIcon, QTooltip, QBtn, QPopupProxy, QField, QEditor } from "quasar";
3
3
  const lang$1 = {
4
4
  isoName: "en-US",
5
5
  yes: "Yes",
@@ -36,6 +36,9 @@ const lang$1 = {
36
36
  },
37
37
  datePicker: {
38
38
  placeholder: "YYYY/MM/DD",
39
+ YYYY: "YYYY",
40
+ MM: "MM",
41
+ DD: "DD",
39
42
  validations: {
40
43
  unavailableRange: "The selected period contains unavailable dates."
41
44
  }
@@ -49,7 +52,7 @@ var define_import_meta_env_default = { BASE_URL: "/", MODE: "production", DEV: f
49
52
  const lang = ref(lang$1);
50
53
  const locales = /* @__PURE__ */ Object.assign({
51
54
  "./en-US.ts": () => Promise.resolve().then(() => enUS),
52
- "./nl.ts": () => import("./nl-VodfMDVb.js")
55
+ "./nl.ts": () => import("./nl-BjtwxTCz.js")
53
56
  });
54
57
  const useLang = () => {
55
58
  return lang;
@@ -329,39 +332,128 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
329
332
  __name: "DateInput",
330
333
  props: {
331
334
  modelValue: {},
332
- label: {},
335
+ format: { default: "YYYY-MM-DD" },
336
+ locale: { default: "en-US" },
337
+ label: { default: "" },
333
338
  required: { type: Boolean },
334
339
  clearable: { type: Boolean },
335
- date: {}
340
+ date: { default: () => ({}) }
336
341
  },
337
342
  emits: ["update:modelValue"],
338
343
  setup(__props, { emit: __emit }) {
339
344
  const props = __props;
340
345
  const emit = __emit;
341
- const attrs = useAttrs();
342
346
  const lang2 = useLang();
343
- const $q = useQuasar();
344
- if (lang2.value.isoName !== $q.lang.isoName)
345
- loadLang($q.lang.isoName);
346
- watch($q.lang, () => {
347
- loadLang($q.lang.isoName);
347
+ const { modelValue, format, locale } = toRefs(props);
348
+ const year = ref();
349
+ const month = ref();
350
+ const day = ref();
351
+ const setYear = (val) => {
352
+ const nr = Number(val);
353
+ if (nr && nr > 1e3 && nr < 1e4)
354
+ year.value = nr;
355
+ };
356
+ const setMonth = (val) => {
357
+ const nr = Number(val);
358
+ if (nr && nr > 0 && nr < 13)
359
+ month.value = nr;
360
+ else
361
+ month.value = void 0;
362
+ };
363
+ const setDay = (val) => {
364
+ const nr = Number(val);
365
+ if (nr && nr > 0 && nr < 32)
366
+ day.value = nr;
367
+ else
368
+ day.value = void 0;
369
+ };
370
+ const setInternalDate = (dateString, separator = "-") => {
371
+ if (dateString) {
372
+ const [yearPart, monthPart, dayPart] = dateString.split(separator);
373
+ if (yearPart && monthPart && dayPart) {
374
+ year.value = Number(yearPart);
375
+ month.value = Number(monthPart);
376
+ day.value = Number(dayPart);
377
+ }
378
+ }
379
+ };
380
+ const setDate = (value) => {
381
+ setInternalDate(value, "/");
382
+ };
383
+ watch([year, month, day], () => {
384
+ const date = `${year.value}-${String(month.value).padStart(2, "0")}-${String(day.value).padStart(2, "0")}`;
385
+ if (Date.parse(date)) {
386
+ emit("update:modelValue", date);
387
+ } else {
388
+ emit("update:modelValue", "");
389
+ }
348
390
  });
349
- const { modelValue } = toRefs(props);
350
- const update = (val) => {
351
- if (typeof val === "string" || val === null)
352
- emit("update:modelValue", val);
391
+ const formattedDate = computed(() => {
392
+ if (modelValue.value)
393
+ return new Date(Date.parse(modelValue.value)).toLocaleDateString(
394
+ locale.value,
395
+ {
396
+ weekday: "long",
397
+ year: "numeric",
398
+ month: "short",
399
+ day: "numeric"
400
+ }
401
+ );
402
+ return "";
403
+ });
404
+ watch(modelValue, (newVal) => {
405
+ if (newVal)
406
+ setInternalDate(newVal);
407
+ else if (newVal === null) {
408
+ year.value = void 0;
409
+ month.value = void 0;
410
+ day.value = void 0;
411
+ }
412
+ });
413
+ setInternalDate(modelValue.value);
414
+ const goToNextElement = (e) => {
415
+ var _a, _b, _c, _d;
416
+ if (["Minus", "Slash"].includes(e.code)) {
417
+ e.preventDefault();
418
+ const next = (_d = (_c = (_b = (_a = e.currentTarget.parentElement) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.parentElement) == null ? void 0 : _c.parentElement) == null ? void 0 : _d.nextElementSibling;
419
+ if (next) {
420
+ next.focus();
421
+ }
422
+ }
353
423
  };
354
- watch(
355
- () => modelValue == null ? void 0 : modelValue.value,
356
- (newVal) => {
357
- if (newVal === "")
358
- emit("update:modelValue", null);
424
+ const dateProps = computed(() => ({
425
+ YYYY: {
426
+ modelValue: year.value,
427
+ placeholder: lang2.value.datePicker.YYYY,
428
+ style: "max-width: 6ch",
429
+ suffix: format.value === "YYYY-MM-DD" ? "-" : void 0,
430
+ class: format.value !== "YYYY-MM-DD" ? "q-mb-none q-ml-xs" : void 0,
431
+ "onUpdate:modelValue": setYear,
432
+ onKeydown: goToNextElement
433
+ },
434
+ MM: {
435
+ modelValue: month.value ? String(month.value).padStart(2, "0") : "",
436
+ placeholder: lang2.value.datePicker.MM,
437
+ style: "max-width: 4ch",
438
+ suffix: "-",
439
+ class: "q-ml-xs",
440
+ "onUpdate:modelValue": setMonth,
441
+ onKeydown: goToNextElement
442
+ },
443
+ DD: {
444
+ modelValue: day.value ? String(day.value).padStart(2, "0") : "",
445
+ placeholder: lang2.value.datePicker.DD,
446
+ style: "max-width: 4ch",
447
+ suffix: format.value === "DD-MM-YYYY" ? "-" : void 0,
448
+ class: format.value === "YYYY-MM-DD" ? "q-ml-xs" : void 0,
449
+ "onUpdate:modelValue": setDay,
450
+ onKeydown: goToNextElement
359
451
  }
360
- );
452
+ }));
361
453
  const validations = ref([
362
454
  (v) => {
363
455
  if (v !== null)
364
- return /^\d{4}\/(0?[1-9]|1[012])\/(0?[1-9]|[12][0-9]|3[01])$/.test(v);
456
+ return /^\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$/.test(v);
365
457
  return true;
366
458
  }
367
459
  ]);
@@ -371,55 +463,69 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
371
463
  );
372
464
  return (_ctx, _cache) => {
373
465
  const _component_q_icon = QIcon;
466
+ const _component_q_tooltip = QTooltip;
374
467
  const _component_q_btn = QBtn;
375
- const _component_q_date = QDate;
376
468
  const _component_q_popup_proxy = QPopupProxy;
469
+ const _component_q_field = QField;
377
470
  const _directive_close_popup = resolveDirective("close-popup");
378
- return openBlock(), createBlock(unref(QInput), mergeProps(unref(attrs), {
379
- rules: validations.value,
471
+ return openBlock(), createBlock(_component_q_field, {
380
472
  "model-value": unref(modelValue),
381
- label: `${_ctx.label}${_ctx.required ? "*" : ""}`,
382
- placeholder: unref(lang2).datePicker.placeholder,
383
- mask: "date",
384
- class: "q-pr-md",
385
- "onUpdate:modelValue": update
386
- }), {
473
+ "bottom-slots": "",
474
+ rules: validations.value
475
+ }, {
476
+ control: withCtx(() => [
477
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(format).split("-"), (part) => {
478
+ return openBlock(), createBlock(resolveDynamicComponent(unref(QInput)), mergeProps({
479
+ key: part,
480
+ borderless: ""
481
+ }, dateProps.value[part]), null, 16);
482
+ }), 128))
483
+ ]),
387
484
  append: withCtx(() => [
388
485
  _ctx.clearable ? (openBlock(), createBlock(_component_q_icon, {
389
486
  key: 0,
390
487
  name: "clear",
391
488
  class: "cursor-pointer",
392
- onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:modelValue", null))
489
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("update:modelValue", null))
393
490
  })) : createCommentVNode("", true),
394
491
  createVNode(_component_q_icon, {
395
492
  name: "event",
396
493
  class: "cursor-pointer"
397
494
  }, {
398
495
  default: withCtx(() => [
496
+ formattedDate.value ? (openBlock(), createBlock(_component_q_tooltip, { key: 0 }, {
497
+ default: withCtx(() => [
498
+ createTextVNode(toDisplayString(formattedDate.value), 1)
499
+ ]),
500
+ _: 1
501
+ })) : createCommentVNode("", true),
399
502
  createVNode(_component_q_popup_proxy, {
400
503
  cover: "",
401
504
  "transition-show": "scale",
402
505
  "transition-hide": "scale"
403
506
  }, {
404
- default: withCtx(() => [
405
- createVNode(_component_q_date, mergeProps(_ctx.date, {
406
- "model-value": unref(modelValue),
407
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.$emit("update:modelValue", $event))
408
- }), {
409
- default: withCtx(() => [
410
- createElementVNode("div", _hoisted_1, [
411
- withDirectives(createVNode(_component_q_btn, {
412
- label: unref(lang2).buttons.close,
413
- color: "primary",
414
- flat: ""
415
- }, null, 8, ["label"]), [
416
- [_directive_close_popup]
507
+ default: withCtx(() => {
508
+ var _a;
509
+ return [
510
+ createVNode(unref(QDate), mergeProps(_ctx.date, {
511
+ "model-value": (_a = unref(modelValue)) == null ? void 0 : _a.replaceAll("-", "/"),
512
+ "onUpdate:modelValue": setDate
513
+ }), {
514
+ default: withCtx(() => [
515
+ createElementVNode("div", _hoisted_1, [
516
+ withDirectives(createVNode(_component_q_btn, {
517
+ label: unref(lang2).buttons.close,
518
+ color: "primary",
519
+ flat: ""
520
+ }, null, 8, ["label"]), [
521
+ [_directive_close_popup]
522
+ ])
417
523
  ])
418
- ])
419
- ]),
420
- _: 1
421
- }, 16, ["model-value"])
422
- ]),
524
+ ]),
525
+ _: 1
526
+ }, 16, ["model-value"])
527
+ ];
528
+ }),
423
529
  _: 1
424
530
  })
425
531
  ]),
@@ -427,7 +533,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
427
533
  })
428
534
  ]),
429
535
  _: 1
430
- }, 16, ["rules", "model-value", "label", "placeholder"]);
536
+ }, 8, ["model-value", "rules"]);
431
537
  };
432
538
  }
433
539
  });
package/dist/general.js CHANGED
@@ -1,7 +1,7 @@
1
- import { l as loadLang, u as useLang, _ as _sfc_main$4 } from "./QSubmitButton.vue_vue_type_script_setup_true_lang-3DA1OTeA.js";
1
+ import { l as loadLang, u as useLang, _ as _sfc_main$4 } from "./QSubmitButton.vue_vue_type_script_setup_true_lang-DAnZaTMl.js";
2
2
  import { useQuasar, QCard, QCardSection, QCardActions, QDialog, QBtn, QToolbarTitle, QToolbar, QHeader, QPage, QPageContainer, QLayout, QSpace, QPageSticky, QSelect, QItemSection, QItemLabel, QItem } from "quasar";
3
3
  import { defineComponent, watch, ref, openBlock, createBlock, unref, withCtx, renderSlot, createVNode, createElementVNode, normalizeProps, guardReactiveProps, normalizeClass, createCommentVNode, toRefs, useAttrs, computed, mergeProps, createTextVNode, toDisplayString } from "vue";
4
- import { e as enUs, n as nl } from "./en-US-Ub0VDpRf.js";
4
+ import { e as enUs, n as nl } from "./en-US-Duo_j_eL.js";
5
5
  const _hoisted_1$1 = { class: "text-h6" };
6
6
  const _hoisted_2 = { class: "text-subtitle2" };
7
7
  const __default__$2 = {
@@ -34,6 +34,9 @@ const lang = {
34
34
  },
35
35
  datePicker: {
36
36
  placeholder: "JJJJ/MM/DD",
37
+ YYYY: "JJJJ",
38
+ MM: "MM",
39
+ DD: "DD",
37
40
  validations: {
38
41
  unavailableRange: "De geselecteerde periode bevat ongeschikbare datums."
39
42
  }
package/dist/style.css CHANGED
@@ -1,4 +1,14 @@
1
1
  .card[data-v-302df27a] {
2
2
  width: 100%;
3
3
  max-width: 300px;
4
- }
4
+ }
5
+ .q-field--auto-height .q-field__control,
6
+ .q-field--auto-height .q-field__native {
7
+ min-height: 1em;
8
+ }
9
+ .q-field--borderless .q-field__bottom,
10
+ .q-field--borderless.q-field--dense .q-field__control,
11
+ .q-field--standard .q-field__bottom,
12
+ .q-field--standard.q-field--dense .q-field__control {
13
+ padding-top: 0;
14
+ }
@@ -1,16 +1,33 @@
1
- import { QDateProps } from 'quasar';
1
+ import { QDateProps, QuasarLanguageCodes } from 'quasar';
2
2
  export interface Props {
3
- modelValue?: string | null;
3
+ modelValue: string | null;
4
+ format?: 'YYYY-MM-DD' | 'DD-MM-YYYY' | 'MM-DD-YYYY';
5
+ locale?: QuasarLanguageCodes;
4
6
  label?: string;
5
7
  required?: boolean;
6
8
  clearable?: boolean;
7
9
  date?: Partial<QDateProps>;
8
10
  }
9
- declare const _default: import("vue").DefineComponent<__VLS_TypePropsToRuntimeProps<Props>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
+ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<Props>, {
12
+ format: string;
13
+ locale: string;
14
+ label: string;
15
+ date: () => {};
16
+ }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
10
17
  "update:modelValue": (val: string | null) => void;
11
- }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_TypePropsToRuntimeProps<Props>>> & {
18
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<Props>, {
19
+ format: string;
20
+ locale: string;
21
+ label: string;
22
+ date: () => {};
23
+ }>>> & {
12
24
  "onUpdate:modelValue"?: ((val: string | null) => any) | undefined;
13
- }, {}, {}>;
25
+ }, {
26
+ label: string;
27
+ date: Partial<QDateProps>;
28
+ format: "YYYY-MM-DD" | "DD-MM-YYYY" | "MM-DD-YYYY";
29
+ locale: keyof import("quasar").QuasarLanguageCodesHolder;
30
+ }, {}>;
14
31
  export default _default;
15
32
  type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
16
33
  type __VLS_TypePropsToRuntimeProps<T> = {
@@ -21,3 +38,11 @@ type __VLS_TypePropsToRuntimeProps<T> = {
21
38
  required: true;
22
39
  };
23
40
  };
41
+ type __VLS_WithDefaults<P, D> = {
42
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
43
+ default: D[K];
44
+ }> : P[K];
45
+ };
46
+ type __VLS_Prettify<T> = {
47
+ [K in keyof T]: T[K];
48
+ } & {};
@@ -34,6 +34,9 @@ export interface Language {
34
34
  };
35
35
  datePicker: {
36
36
  placeholder: string;
37
+ YYYY: string;
38
+ MM: string;
39
+ DD: string;
37
40
  validations: {
38
41
  unavailableRange: string;
39
42
  };
@@ -76,6 +79,9 @@ export declare const lang: Ref<{
76
79
  };
77
80
  datePicker: {
78
81
  placeholder: string;
82
+ YYYY: string;
83
+ MM: string;
84
+ DD: string;
79
85
  validations: {
80
86
  unavailableRange: string;
81
87
  };
@@ -37,17 +37,17 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
37
  import { promises } from 'fs';
38
38
  import { Icon, FlagIcon } from './virtualModules.js';
39
39
  var readFile = promises.readFile;
40
- export default function (_a) {
41
- var _b = _a === void 0 ? {} : _a, buildFromSrc = _b.buildFromSrc;
42
- return __awaiter(this, void 0, void 0, function () {
43
- var pkgJson, _c, _d, exports, name;
40
+ export default function () {
41
+ return __awaiter(this, arguments, void 0, function (_a) {
42
+ var pkgJson, _b, _c, exports, name;
43
+ var _d = _a === void 0 ? {} : _a, buildFromSrc = _d.buildFromSrc;
44
44
  return __generator(this, function (_e) {
45
45
  switch (_e.label) {
46
46
  case 0:
47
- _d = (_c = JSON).parse;
47
+ _c = (_b = JSON).parse;
48
48
  return [4 /*yield*/, readFile(new URL('../package.json', import.meta.url).pathname, 'utf-8')];
49
49
  case 1:
50
- pkgJson = _d.apply(_c, [_e.sent()]);
50
+ pkgJson = _c.apply(_b, [_e.sent()]);
51
51
  exports = pkgJson.exports;
52
52
  name = pkgJson.name;
53
53
  return [2 /*return*/, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simsustech/quasar-components",
3
- "version": "0.4.8",
3
+ "version": "0.5.0",
4
4
  "author": "Stefan van Herwijnen",
5
5
  "description": "High level components for Quasar Framework",
6
6
  "license": "MIT",
@@ -52,26 +52,26 @@
52
52
  "quasar": "^2.9.2"
53
53
  },
54
54
  "devDependencies": {
55
- "@types/node": "^20.11.16",
56
- "@types/validator": "^13.11.8",
55
+ "@types/node": "^20.11.19",
56
+ "@types/validator": "^13.11.9",
57
57
  "@types/ws": "^8.5.10",
58
- "@typescript-eslint/eslint-plugin": "^6.20.0",
59
- "@typescript-eslint/parser": "^6.20.0",
60
- "@vitejs/plugin-vue": "^5.0.3",
61
- "@vue/server-renderer": "^3.4.15",
58
+ "@typescript-eslint/eslint-plugin": "^7.0.1",
59
+ "@typescript-eslint/parser": "^7.0.1",
60
+ "@vitejs/plugin-vue": "^5.0.4",
61
+ "@vue/server-renderer": "^3.4.19",
62
62
  "eslint": "^8.56.0",
63
63
  "eslint-config-prettier": "^9.1.0",
64
64
  "eslint-plugin-prettier-vue": "^5.0.0",
65
65
  "eslint-plugin-vue": "^9.21.1",
66
66
  "glob": "^10.3.10",
67
67
  "local-pkg": "^0.5.0",
68
- "prettier": "^3.2.4",
69
- "quasar": "^2.14.3",
68
+ "prettier": "^3.2.5",
69
+ "quasar": "^2.14.4",
70
70
  "rimraf": "^5.0.5",
71
71
  "typescript": "^5.3.3",
72
72
  "unplugin-vue-components": "^0.26.0",
73
- "vite": "^5.0.12",
74
- "vue": "^3.4.15",
73
+ "vite": "^5.1.3",
74
+ "vue": "^3.4.19",
75
75
  "vue-router": "^4.2.5",
76
76
  "vue-tsc": "^1.8.27"
77
77
  },
@@ -15,6 +15,7 @@
15
15
  bottom-slots
16
16
  :rules="validations['email']"
17
17
  lazy-rules
18
+ autcomplete="email"
18
19
  />
19
20
  <q-input
20
21
  v-if="useUsername"
@@ -26,6 +27,7 @@
26
27
  bottom-slots
27
28
  :rules="validations['username']"
28
29
  lazy-rules
30
+ autocomplete="username"
29
31
  />
30
32
  <q-input
31
33
  id="password"
@@ -38,6 +40,7 @@
38
40
  :rules="validations['password']"
39
41
  lazy-rules
40
42
  bottom-slots
43
+ autcomplete="current-password"
41
44
  >
42
45
  <template #append>
43
46
  <q-icon
@@ -1,27 +1,31 @@
1
1
  <template>
2
- <q-input
3
- v-bind="attrs"
4
- :rules="validations"
5
- :model-value="modelValue"
6
- :label="`${label}${required ? '*' : ''}`"
7
- :placeholder="lang.datePicker.placeholder"
8
- mask="date"
9
- class="q-pr-md"
10
- @update:model-value="update"
11
- >
12
- <template v-slot:append>
2
+ <q-field :model-value="modelValue" bottom-slots :rules="validations">
3
+ <template #control>
4
+ <component
5
+ :is="QInput"
6
+ v-for="part in format.split('-')"
7
+ :key="part"
8
+ borderless
9
+ v-bind="dateProps[part]"
10
+ />
11
+ </template>
12
+
13
+ <template #append>
13
14
  <q-icon
14
15
  v-if="clearable"
15
16
  name="clear"
16
17
  class="cursor-pointer"
17
- @click="$emit('update:modelValue', null)"
18
+ @click="emit('update:modelValue', null)"
18
19
  />
19
20
  <q-icon name="event" class="cursor-pointer">
21
+ <q-tooltip v-if="formattedDate">
22
+ {{ formattedDate }}
23
+ </q-tooltip>
20
24
  <q-popup-proxy cover transition-show="scale" transition-hide="scale">
21
25
  <q-date
22
26
  v-bind="date"
23
- :model-value="modelValue"
24
- @update:model-value="$emit('update:modelValue', $event)"
27
+ :model-value="modelValue?.replaceAll('-', '/')"
28
+ @update:model-value="setDate"
25
29
  >
26
30
  <div class="row items-center justify-end">
27
31
  <q-btn
@@ -35,51 +39,170 @@
35
39
  </q-popup-proxy>
36
40
  </q-icon>
37
41
  </template>
38
- </q-input>
42
+ </q-field>
39
43
  </template>
40
44
 
41
45
  <script setup lang="ts">
42
- import { ref, watch, useAttrs, toRefs } from 'vue'
43
- import { QDateProps, QInput, useQuasar } from 'quasar'
44
- import { useLang, loadLang } from './lang'
46
+ import { ref, watch, toRefs, computed } from 'vue'
47
+ import {
48
+ QDate,
49
+ QDateProps,
50
+ QInput,
51
+ QInputProps,
52
+ QuasarLanguageCodes
53
+ } from 'quasar'
54
+ import { useLang } from './lang'
45
55
 
46
56
  export interface Props {
47
- modelValue?: string | null
57
+ modelValue: string | null
58
+ format?: 'YYYY-MM-DD' | 'DD-MM-YYYY' | 'MM-DD-YYYY'
59
+ locale?: QuasarLanguageCodes
48
60
  label?: string
49
61
  required?: boolean
50
62
  clearable?: boolean
51
63
  date?: Partial<QDateProps>
52
64
  }
53
- const props = defineProps<Props>()
65
+ const props = withDefaults(defineProps<Props>(), {
66
+ format: 'YYYY-MM-DD',
67
+ locale: 'en-US',
68
+ label: '',
69
+ date: () => ({})
70
+ })
54
71
  const emit = defineEmits<{
55
72
  (e: 'update:modelValue', val: string | null): void
56
73
  }>()
57
- const attrs = useAttrs()
74
+ // const attrs = useAttrs()
58
75
 
59
76
  const lang = useLang()
60
77
 
61
- const $q = useQuasar()
62
- if (lang.value.isoName !== $q.lang.isoName) loadLang($q.lang.isoName)
63
- watch($q.lang, () => {
64
- loadLang($q.lang.isoName)
78
+ const { modelValue, format, locale } = toRefs(props)
79
+
80
+ const year = ref<number>()
81
+ const month = ref<number>()
82
+ const day = ref<number>()
83
+
84
+ const setYear: InstanceType<typeof QInput>['$props']['onUpdate:modelValue'] = (
85
+ val
86
+ ) => {
87
+ const nr = Number(val)
88
+ if (nr && nr > 1e3 && nr < 1e4) year.value = nr
89
+ }
90
+
91
+ const setMonth: InstanceType<typeof QInput>['$props']['onUpdate:modelValue'] = (
92
+ val
93
+ ) => {
94
+ const nr = Number(val)
95
+ if (nr && nr > 0 && nr < 13) month.value = nr
96
+ else month.value = undefined
97
+ }
98
+
99
+ const setDay: InstanceType<typeof QInput>['$props']['onUpdate:modelValue'] = (
100
+ val
101
+ ) => {
102
+ const nr = Number(val)
103
+ if (nr && nr > 0 && nr < 32) day.value = nr
104
+ else day.value = undefined
105
+ }
106
+
107
+ const setInternalDate = (
108
+ dateString?: string | null,
109
+ separator: '-' | '/' = '-'
110
+ ) => {
111
+ if (dateString) {
112
+ const [yearPart, monthPart, dayPart] = dateString.split(separator)
113
+ if (yearPart && monthPart && dayPart) {
114
+ year.value = Number(yearPart)
115
+ month.value = Number(monthPart)
116
+ day.value = Number(dayPart)
117
+ }
118
+ }
119
+ }
120
+
121
+ const setDate: InstanceType<typeof QDate>['$props']['onUpdate:modelValue'] = (
122
+ value
123
+ ) => {
124
+ setInternalDate(value, '/')
125
+ }
126
+
127
+ watch([year, month, day], () => {
128
+ const date = `${year.value}-${String(month.value).padStart(2, '0')}-${String(day.value).padStart(2, '0')}`
129
+ if (Date.parse(date)) {
130
+ emit('update:modelValue', date)
131
+ } else {
132
+ emit('update:modelValue', '')
133
+ }
65
134
  })
66
135
 
67
- const { modelValue } = toRefs(props)
136
+ const formattedDate = computed(() => {
137
+ if (modelValue.value)
138
+ return new Date(Date.parse(modelValue.value)).toLocaleDateString(
139
+ locale.value,
140
+ {
141
+ weekday: 'long',
142
+ year: 'numeric',
143
+ month: 'short',
144
+ day: 'numeric'
145
+ }
146
+ )
147
+ return ''
148
+ })
68
149
 
69
- const update = (val: string | number | null) => {
70
- if (typeof val === 'string' || val === null) emit('update:modelValue', val)
150
+ watch(modelValue, (newVal) => {
151
+ if (newVal) setInternalDate(newVal)
152
+ else if (newVal === null) {
153
+ year.value = undefined
154
+ month.value = undefined
155
+ day.value = undefined
156
+ }
157
+ })
158
+ setInternalDate(modelValue.value)
159
+
160
+ const goToNextElement = (e: KeyboardEvent) => {
161
+ if (['Minus', 'Slash'].includes(e.code)) {
162
+ e.preventDefault()
163
+ const next = (e.currentTarget as HTMLElement).parentElement?.parentElement
164
+ ?.parentElement?.parentElement?.nextElementSibling
165
+ if (next) {
166
+ ;(next as HTMLElement).focus()
167
+ }
168
+ }
71
169
  }
72
- watch(
73
- () => modelValue?.value,
74
- (newVal) => {
75
- if (newVal === '') emit('update:modelValue', null)
170
+
171
+ const dateProps = computed<Record<string, QInputProps>>(() => ({
172
+ YYYY: {
173
+ modelValue: year.value,
174
+ placeholder: lang.value.datePicker.YYYY,
175
+ style: 'max-width: 6ch',
176
+ suffix: format.value === 'YYYY-MM-DD' ? '-' : undefined,
177
+ class: format.value !== 'YYYY-MM-DD' ? 'q-mb-none q-ml-xs' : undefined,
178
+ 'onUpdate:modelValue': setYear,
179
+ onKeydown: goToNextElement
180
+ },
181
+ MM: {
182
+ modelValue: month.value ? String(month.value).padStart(2, '0') : '',
183
+ placeholder: lang.value.datePicker.MM,
184
+ style: 'max-width: 4ch',
185
+ suffix: '-',
186
+ class: 'q-ml-xs',
187
+ 'onUpdate:modelValue': setMonth,
188
+ onKeydown: goToNextElement
189
+ },
190
+ DD: {
191
+ modelValue: day.value ? String(day.value).padStart(2, '0') : '',
192
+ placeholder: lang.value.datePicker.DD,
193
+ style: 'max-width: 4ch',
194
+ suffix: format.value === 'DD-MM-YYYY' ? '-' : undefined,
195
+ class: format.value === 'YYYY-MM-DD' ? 'q-ml-xs' : undefined,
196
+ 'onUpdate:modelValue': setDay,
197
+ onKeydown: goToNextElement
76
198
  }
77
- )
199
+ }))
78
200
 
79
201
  const validations = ref<((val: string) => boolean | string)[]>([
80
202
  (v) => {
81
203
  if (v !== null)
82
- return /^\d{4}\/(0?[1-9]|1[012])\/(0?[1-9]|[12][0-9]|3[01])$/.test(v)
204
+ // return /^\d{4}\/(0?[1-9]|1[012])\/(0?[1-9]|[12][0-9]|3[01])$/.test(v)
205
+ return /^\d{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$/.test(v)
83
206
  return true
84
207
  }
85
208
  ])
@@ -89,3 +212,16 @@ if (props.required)
89
212
  (val: string) => !!val || lang.value.validations.fieldRequired
90
213
  )
91
214
  </script>
215
+
216
+ <style>
217
+ .q-field--auto-height .q-field__control,
218
+ .q-field--auto-height .q-field__native {
219
+ min-height: 1em;
220
+ }
221
+ .q-field--borderless .q-field__bottom,
222
+ .q-field--borderless.q-field--dense .q-field__control,
223
+ .q-field--standard .q-field__bottom,
224
+ .q-field--standard.q-field--dense .q-field__control {
225
+ padding-top: 0;
226
+ }
227
+ </style>
@@ -36,6 +36,9 @@ const lang: Language = {
36
36
  },
37
37
  datePicker: {
38
38
  placeholder: 'YYYY/MM/DD',
39
+ YYYY: 'YYYY',
40
+ MM: 'MM',
41
+ DD: 'DD',
39
42
  validations: {
40
43
  unavailableRange: 'The selected period contains unavailable dates.'
41
44
  }
@@ -34,6 +34,9 @@ export interface Language {
34
34
  }
35
35
  datePicker: {
36
36
  placeholder: string
37
+ YYYY: string
38
+ MM: string
39
+ DD: string
37
40
  validations: {
38
41
  unavailableRange: string
39
42
  }
@@ -36,6 +36,9 @@ const lang: Language = {
36
36
  },
37
37
  datePicker: {
38
38
  placeholder: 'JJJJ/MM/DD',
39
+ YYYY: 'JJJJ',
40
+ MM: 'MM',
41
+ DD: 'DD',
39
42
  validations: {
40
43
  unavailableRange: 'De geselecteerde periode bevat ongeschikbare datums.'
41
44
  }
File without changes
File without changes
File without changes