@ekzo-dev/bootstrap-addons 5.2.16 → 5.2.18

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ekzo-dev/bootstrap-addons",
3
3
  "description": "Aurelia Bootstrap additional component",
4
- "version": "5.2.16",
4
+ "version": "5.2.18",
5
5
  "homepage": "https://github.com/ekzo-dev/aurelia-components/tree/main/packages/bootstrap-addons",
6
6
  "repository": {
7
7
  "type": "git",
@@ -9,16 +9,20 @@
9
9
  },
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
- "@ekzo-dev/bootstrap": "^5.2.11",
12
+ "@ekzo-dev/bootstrap": "^5.2.18",
13
13
  "@ekzo-dev/vanilla-jsoneditor": "^0.23.7",
14
14
  "@ekzo-dev/toolkit": "^1.2.4",
15
15
  "@fortawesome/free-solid-svg-icons": "^6.5.2",
16
16
  "@types/json-schema": "^7.0.14",
17
+ "@formatjs/intl-durationformat": "^0.7.1",
17
18
  "ajv": "^8.17.1",
18
19
  "ajv-formats": "^3.0.1",
19
20
  "vanilla-jsoneditor": "~0.23.0",
20
21
  "immutable-json-patch": "^5.1.3"
21
22
  },
23
+ "peerDependencies": {
24
+ "bootstrap": "^5.2.3"
25
+ },
22
26
  "main": "src/index.ts",
23
27
  "files": [
24
28
  "src"
@@ -0,0 +1,21 @@
1
+ <template class="${floatingLabel ? 'form-floating' : ''}">
2
+ <label for="${id}" if.bind="label && !floatingLabel" class="form-label">${label}</label>
3
+ <fieldset class="${classes}" id="${id}" disabled.bind="disabled">
4
+ <input type="number" min="0" value.bind="duration.years" disabled.bind="disabled" placeholder="--" />
5
+ ${labels.years}
6
+ <input type="number" min="0" value.bind="duration.months" disabled.bind="disabled" placeholder="--" />
7
+ ${labels.months}
8
+ <input type="number" min="0" value.bind="duration.days" disabled.bind="disabled" placeholder="--" />
9
+ ${labels.days}
10
+ <input type="number" min="0" value.bind="duration.hours" disabled.bind="disabled" placeholder="--" />
11
+ ${labels.hours}
12
+ <input type="number" min="0" value.bind="duration.minutes" disabled.bind="disabled" placeholder="--" />
13
+ ${labels.minutes}
14
+ <input type="number" min="0" value.bind="duration.seconds" disabled.bind="disabled" placeholder="--" />
15
+ ${labels.seconds}
16
+ <input if.bind="required" required value.bind="value" />
17
+ </fieldset>
18
+ <label for="${id}" if.bind="label && floatingLabel"><span>${label}</span></label>
19
+ <div class="invalid-feedback" if.bind="invalidFeedback">${invalidFeedback}</div>
20
+ <div class="valid-feedback" if.bind="validFeedback">${validFeedback}</div>
21
+ </template>
@@ -0,0 +1,46 @@
1
+ @import 'bootstrap/scss/functions';
2
+ @import 'bootstrap/scss/variables';
3
+ @import 'bootstrap/scss/maps';
4
+ @import 'bootstrap/scss/mixins';
5
+ @import 'bootstrap/scss/forms/form-control';
6
+
7
+ bs-duration-input {
8
+ display: block;
9
+
10
+ fieldset {
11
+ position: relative;
12
+ }
13
+
14
+ input[type='number'] {
15
+ border: 0;
16
+ min-inline-size: 2ch;
17
+ appearance: textfield;
18
+ outline: 0;
19
+ text-align: right;
20
+ field-sizing: content;
21
+
22
+ &::-webkit-outer-spin-button,
23
+ &::-webkit-inner-spin-button {
24
+ appearance: none;
25
+ margin: 0;
26
+ }
27
+ }
28
+
29
+ input[required] {
30
+ position: absolute;
31
+ height: 100%;
32
+ width: 100%;
33
+ left: 0;
34
+ bottom: 0;
35
+ opacity: 0;
36
+ pointer-events: none;
37
+ }
38
+ }
39
+
40
+ @supports not (field-sizing: content) {
41
+ bs-duration-input {
42
+ input[type='number'] {
43
+ inline-size: 3ch;
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,40 @@
1
+ import { BsButton } from '@ekzo-dev/bootstrap';
2
+ import { createComponentTemplate, Meta, Story, StoryFnAureliaReturnType } from '@storybook/aurelia';
3
+
4
+ import { selectControl } from '../../../../../.storybook/helpers';
5
+
6
+ import { BsDurationInput } from '.';
7
+
8
+ const meta: Meta = {
9
+ title: 'Ekzo / Bootstrap Addons / Forms / Duration input',
10
+ component: BsDurationInput,
11
+ args: {
12
+ value: 'P5DT1H',
13
+ label: 'Duration',
14
+ },
15
+ argTypes: {
16
+ bsSize: selectControl(['', 'sm', 'lg']),
17
+ },
18
+ };
19
+
20
+ export default meta;
21
+
22
+ const Overview: Story = (args): StoryFnAureliaReturnType => ({
23
+ props: args,
24
+ });
25
+
26
+ const Validation: Story = (args): StoryFnAureliaReturnType => ({
27
+ props: args,
28
+ template: `<form class='was-validated'>${createComponentTemplate(
29
+ BsDurationInput
30
+ )}<br><button bs-button>Validate</button></form>`,
31
+ components: [BsButton],
32
+ });
33
+
34
+ Validation.args = {
35
+ required: true,
36
+ floatingLabel: true,
37
+ };
38
+
39
+ // eslint-disable-next-line
40
+ export { Overview, Validation };
@@ -0,0 +1,95 @@
1
+ import template from './duration-input.html';
2
+
3
+ import './duration-input.scss';
4
+
5
+ import '@formatjs/intl-durationformat/polyfill';
6
+
7
+ import { BaseField, Size } from '@ekzo-dev/bootstrap';
8
+ import { coerceBoolean } from '@ekzo-dev/toolkit';
9
+ import { bindable, BindingMode, customElement } from 'aurelia';
10
+
11
+ interface IDuration {
12
+ years?: string;
13
+ months?: string;
14
+ days?: string;
15
+ hours?: string;
16
+ minutes?: string;
17
+ seconds?: string;
18
+ }
19
+
20
+ @customElement({
21
+ name: 'bs-duration-input',
22
+ template,
23
+ })
24
+ export class BsDurationInput extends BaseField {
25
+ @bindable({ mode: BindingMode.twoWay })
26
+ get value(): string {
27
+ const { years, months, days, hours, minutes, seconds } = this.duration;
28
+
29
+ const date = `${years ? years + 'Y' : ''}${months ? months + 'M' : ''}${days ? days + 'D' : ''}`;
30
+ const time = `${hours ? hours + 'H' : ''}${minutes ? minutes + 'M' : ''}${seconds ? seconds + 'S' : ''}`;
31
+
32
+ return date || time ? `P${date}${time ? 'T' + time : ''}` : '';
33
+ }
34
+ set value(value: string | null | undefined) {
35
+ const match = value?.match(/^P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/);
36
+
37
+ if (match) {
38
+ this.duration = {
39
+ years: match[1],
40
+ months: match[2],
41
+ days: match[3],
42
+ hours: match[4],
43
+ minutes: match[5],
44
+ seconds: match[6],
45
+ };
46
+ } else {
47
+ this.duration = {};
48
+ }
49
+ }
50
+
51
+ @bindable()
52
+ bsSize?: Size;
53
+
54
+ @bindable(coerceBoolean)
55
+ floatingLabel: boolean = false;
56
+
57
+ duration: IDuration = {};
58
+
59
+ labels: IDuration = this.#getLabels();
60
+
61
+ get classes(): string {
62
+ return [
63
+ 'form-control',
64
+ this.bsSize ? `form-control-${this.bsSize}` : null,
65
+ this.valid === true ? 'is-valid' : null,
66
+ this.valid === false ? 'is-invalid' : null,
67
+ ]
68
+ .filter(Boolean)
69
+ .join(' ');
70
+ }
71
+
72
+ #getLabels(): IDuration {
73
+ const str: string = new Intl['DurationFormat'](navigator.language, { style: 'narrow' }).format({
74
+ years: 1,
75
+ months: 1,
76
+ days: 1,
77
+ hours: 1,
78
+ minutes: 1,
79
+ seconds: 1,
80
+ });
81
+ const labels: string[] = str
82
+ .split('1')
83
+ .slice(1)
84
+ .map((n) => n.trim());
85
+
86
+ return {
87
+ years: labels[0],
88
+ months: labels[1],
89
+ days: labels[2],
90
+ hours: labels[3],
91
+ minutes: labels[4],
92
+ seconds: labels[5],
93
+ };
94
+ }
95
+ }
@@ -0,0 +1 @@
1
+ export * from './duration-input';
@@ -34,7 +34,7 @@
34
34
  form.bind="form & attr"
35
35
  name.bind="name & attr"
36
36
  title.bind="title & attr"
37
- autocomplete.bind="autocomplete & attr"
37
+ autocomplete="off"
38
38
  keydown.trigger="$event.preventDefault()"
39
39
  />
40
40
  <bs-dropdown-menu>
@@ -34,6 +34,7 @@ export class BsSelect extends BaseBsSelect implements ICustomElementViewModel {
34
34
  deactivating: boolean = false;
35
35
 
36
36
  binding() {
37
+ super.binding();
37
38
  this.deactivating = false;
38
39
  }
39
40
 
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
+ export * from './forms/duration-input';
1
2
  export * from './forms/json-input';
2
3
  export * from './forms/select';