Skip to content

Commit

Permalink
feat: mb-duration added to medblocks-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
ATHULKNAIR committed Sep 16, 2021
1 parent d3d4006 commit cb865f3
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 5 deletions.
8 changes: 5 additions & 3 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

<body>
<mb-form>
<div>
<mb-duration year required label="Duration"></mb-duration>
</div>
<!-- <div>
<mb-quantity required label="Somrhting"></mb-quantity>
</div> -->
Expand All @@ -26,7 +29,7 @@
</script>
</div> -->

<div>
<!-- <div>
<mb-checkbox
required
label="Check that"
Expand All @@ -37,8 +40,7 @@
const check = document.getElementById('checkbox')
check.data = true
</script>
</div>

</div> -->
<!-- <div>
<mb-select required id="select">
<mb-option value="mother" label="Mother"></mb-option>
Expand Down
3 changes: 2 additions & 1 deletion medblocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ import './src/medblocks/boolean/checkbox';
import './src/medblocks/proportion/percent';
import './src/medblocks/context/checkboxAny';
import './src/medblocks/text/text-select';
import './src/medblocks/text/input-multiple';
import './src/medblocks/text/input-multiple';
import './src/medblocks/duration/duration';
133 changes: 133 additions & 0 deletions src/medblocks/duration/duration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { customElement, html, property, state, css } from 'lit-element';
import SlInput from '@shoelace-style/shoelace/dist/components/input/input';
import '@shoelace-style/shoelace/dist/components/input/input';
import EhrElement from '../EhrElement';

@customElement('mb-duration')
export default class MbDuration extends EhrElement {
static styles = css`
div {
display: flex;
gap: 10px;
}
.label {
font-size: var(--sl-input-label-font-size-medium);
display: inline-block;
color: var(--sl-input-label-color);
margin-bottom: var(--sl-spacing-xxx-small);
}
sl-input {
width: 0;
flex: 1 1 auto;
}
`;

@property({ type: Boolean, reflect: true }) year: boolean = false;
@property({ type: Boolean, reflect: true }) month: boolean = false;
@property({ type: Boolean, reflect: true }) week: boolean = false;
@property({ type: Boolean, reflect: true }) day: boolean = false;
@property({ type: Boolean, reflect: true }) hour: boolean = false;
@property({ type: Boolean, reflect: true }) minute: boolean = false;
@property({ type: Boolean, reflect: true }) second: boolean = false;
@property({ type: Boolean, reflect: true }) required: boolean = false;

@state() _state : {[period: string]: string | undefined} = {}

parsePeriod(period: string) {
const [periodPart, t] = period.split('T');
const p = periodPart.replace('P', '');
this._state.year = this.getPart(p, 'Y');
this._state.month = this.getPart(p, 'M');
this._state.week = this.getPart(p, 'W');
this._state.day = this.getPart(p, 'D');
if (t) {
this._state.hour = this.getPart(t, 'H');
this._state.minute = this.getPart(t, 'M');
this._state.second = this.getPart(t, 'S');
}
}

getPart(periodPart: string, part: string): string | undefined {
const myRegexp = new RegExp(`(\\d)${part}`, 'g');
const match = myRegexp.exec(periodPart);
return match ? match[1] : undefined;
}

serializePeriod(): string {
const hour = this._state.hour ? `${this._state.hour}H` : '';
const minute = this._state.minute ? `${this._state.minute}M` : '';
const second = this._state.second ? `${this._state.second}S` : '';
const t = [hour, minute, second].join('');

const year = this._state.year ? `${this._state.year}Y` : '';
const month = this._state.month ? `${this._state.month}M` : '';
const week = this._state.week ? `${this._state.week}W` : '';
const day = this._state.day ? `${this._state.day}D` : '';
const p = [year, month, week, day].join('');

const timePart = t ? `T${t}` : '';
const periodPart = p ? `P${p}` : '';

return `${periodPart}${timePart}`;
}

get data() {
return this.serializePeriod();
}

set data(period: string) {
const oldVal = this.data
this.parsePeriod(period);
this.requestUpdate('data',oldVal)
}

handleInput(value:string,e:CustomEvent){
const oldVal = this.data
const target = e.target as SlInput;
this._state = {...this._state, [value]: target.value};
this.requestUpdate('data', oldVal)
this._mbInput.emit()
}

formatDuration(value: string) : string {
return value.charAt(0).toUpperCase() + value.slice(1)+'s'
}

reportValidity() {
if (this.data) {
return true
} else {
const input = this.shadowRoot!.querySelector('sl-input') as SlInput;
return input.reportValidity()
}
}

getInputs() {
const allDurations: any = {
year: this.year, month: this.month, week: this.week,day: this.day, hour: this.hour, minute: this.minute, second: this.second
}
const durationKeys = Object.keys(allDurations)
const toRender = durationKeys.every(a=>allDurations[a]===false) ? durationKeys : durationKeys
.filter(a=>allDurations[a])

return toRender.map(a=>html`<sl-input
id=${a}
type="number"
?required=${this.required}
help-text=${this.formatDuration(a)}
.value=${this._state[a] || ''}
@sl-input=${(e: CustomEvent)=>this.handleInput(a,e)}
></sl-input>`)
}

render(){
return html`
${this.label
? html`<label part="label" class="label">${this.label}</label>`
: null}
<div>
${this.getInputs()}
</div>
`
}
}
38 changes: 38 additions & 0 deletions test/mb-duration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
html,
fixture,
expect,
oneEvent,
elementUpdated,
} from '@open-wc/testing';
import MbDuration from '../src/medblocks/duration/duration';
import '../src/medblocks/duration/duration';
import { querySelectorAllDeep } from 'query-selector-shadow-dom';
import { SlInput } from '@shoelace-style/shoelace';

describe('MbDuration', () => {
it('emits data on input', async () => {
const mbDuration = await fixture<MbDuration>(
html`<mb-duration year=${true} label="Year"></mb-duration>`
);
const year = querySelectorAllDeep('input') as SlInput[];
setTimeout(() => {
year[0].value = '2';
year[0].dispatchEvent(new Event('input'));
});
const event: any = await oneEvent(mbDuration, 'mb-input');
expect(event.target.data).to.eq('P2Y');
});
it('changes input on setting data', async () => {
const mbDuration = await fixture<MbDuration>(
html`<mb-duration year label="Year"></mb-duration>`
);
const year = querySelectorAllDeep('input') as SlInput[];
setTimeout(()=>{
mbDuration.data = 'P3Y';
},0)
await oneEvent(mbDuration, 'mb-input');
await elementUpdated(mbDuration);
expect(year[0].value).to.eq('3');
});
});
59 changes: 59 additions & 0 deletions test/validation-test/duration-validation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import '../../medblocks'
import { expect } from '@open-wc/testing'
import { elementUpdated, fixture } from '@open-wc/testing-helpers'
import { html } from 'lit-html'
import { querySelectorDeep } from 'query-selector-shadow-dom'
import MbForm from '../../src/medblocks/form/form'



describe('duration validation test',()=>{
it('empty',async ()=>{
const form = await fixture<MbForm>(
html`
<mb-form>
<mb-duration year path="test/1"></mb-duration>
</mb-form>
`
)
await elementUpdated(form);
expect(form.validate()).to.be.true
})
it('data',async ()=>{
const form = await fixture<MbForm>(
html`
<mb-form>
<mb-duration year path="test/1"></mb-duration>
</mb-form>
`
)
const duration = querySelectorDeep('mb-duration') as any;
duration.data = 'P2Y3MT2H'
await elementUpdated(form);
expect(form.validate()).to.be.true
})
it('required but empty',async ()=>{
const form = await fixture<MbForm>(
html`
<mb-form>
<mb-duration year required path="test/1"></mb-duration>
</mb-form>
`
)
await elementUpdated(form)
expect(form.validate()).to.be.false
})
it('required with data',async ()=>{
const form = await fixture<MbForm>(
html`
<mb-form>
<mb-duration year required path="test/1"></mb-duration>
</mb-form>
`
)
const duration = querySelectorDeep('mb-duration') as any;
duration.data = 'PT2H'
await elementUpdated(form)
expect(form.validate()).to.be.true
})
})
2 changes: 1 addition & 1 deletion test/validation-test/input-multiple-validation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('input-multiple validation test',()=>{
`
)
const input = querySelectorDeep('mb-input-multiple') as any;
input.data = 'testUnit';
input.data = ['testUnit'];
await elementUpdated(form);
expect(form.validate()).to.be.true
})
Expand Down

0 comments on commit cb865f3

Please sign in to comment.