@operato/property-editor 0.2.5 → 0.2.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.
Files changed (58) hide show
  1. package/.storybook/main.js +2 -2
  2. package/.storybook/server.mjs +4 -4
  3. package/CHANGELOG.md +15 -17
  4. package/LICENSE +2 -2
  5. package/README.md +26 -7
  6. package/custom-elements.json +317 -0
  7. package/demo/index.html +16 -39
  8. package/dist/src/index.d.ts +1 -5
  9. package/dist/src/index.js +1 -5
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/ox-property-editor.d.ts +28 -0
  12. package/dist/src/ox-property-editor.js +161 -0
  13. package/dist/src/ox-property-editor.js.map +1 -0
  14. package/dist/stories/index.stories.d.ts +1 -1
  15. package/dist/stories/index.stories.js +11 -15
  16. package/dist/stories/index.stories.js.map +1 -1
  17. package/dist/test/property-editor.test.d.ts +1 -0
  18. package/dist/test/property-editor.test.js +24 -0
  19. package/dist/test/property-editor.test.js.map +1 -0
  20. package/dist/tsconfig.tsbuildinfo +1 -1
  21. package/package.json +14 -33
  22. package/src/index.ts +1 -5
  23. package/src/ox-property-editor.ts +158 -0
  24. package/stories/index.stories.ts +30 -38
  25. package/test/property-editor.test.ts +34 -0
  26. package/tsconfig.json +2 -2
  27. package/web-dev-server.config.mjs +9 -8
  28. package/web-test-runner.config.mjs +7 -19
  29. package/.editorconfig +0 -29
  30. package/demo/index-3dish.html +0 -22
  31. package/demo/index-angle.html +0 -31
  32. package/demo/index-button-radio.html +0 -30
  33. package/demo/index-checkbox.html +0 -54
  34. package/demo/index-stack.html +0 -21
  35. package/dist/src/ox-buttons-radio.d.ts +0 -28
  36. package/dist/src/ox-buttons-radio.js +0 -90
  37. package/dist/src/ox-buttons-radio.js.map +0 -1
  38. package/dist/src/ox-checkbox.d.ts +0 -16
  39. package/dist/src/ox-checkbox.js +0 -146
  40. package/dist/src/ox-checkbox.js.map +0 -1
  41. package/dist/src/ox-input-3dish.d.ts +0 -30
  42. package/dist/src/ox-input-3dish.js +0 -140
  43. package/dist/src/ox-input-3dish.js.map +0 -1
  44. package/dist/src/ox-input-angle.d.ts +0 -14
  45. package/dist/src/ox-input-angle.js +0 -56
  46. package/dist/src/ox-input-angle.js.map +0 -1
  47. package/dist/src/ox-input-stack.d.ts +0 -21
  48. package/dist/src/ox-input-stack.js +0 -108
  49. package/dist/src/ox-input-stack.js.map +0 -1
  50. package/dist/test/property-angle.test.d.ts +0 -1
  51. package/dist/test/property-angle.test.js +0 -23
  52. package/dist/test/property-angle.test.js.map +0 -1
  53. package/src/ox-buttons-radio.ts +0 -87
  54. package/src/ox-checkbox.ts +0 -141
  55. package/src/ox-input-3dish.ts +0 -150
  56. package/src/ox-input-angle.ts +0 -56
  57. package/src/ox-input-stack.ts +0 -109
  58. package/test/property-angle.test.ts +0 -33
@@ -1 +0,0 @@
1
- {"version":3,"file":"ox-input-stack.js","sourceRoot":"","sources":["../../src/ox-input-stack.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license Copyright © HatioLab Inc. All rights reserved.\n */\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\n@customElement('ox-stack')\nexport default class OxStack extends LitElement {\n static styles = [\n css`\n :host {\n display: block;\n }\n\n #add-floor {\n width: 100%;\n height: 20px;\n background-color: blue;\n color: white;\n }\n\n div {\n background-color: blue;\n width: calc(100% - 40px);\n width: -webkit-calc(100% - 40px);\n min-height: 20px;\n }\n\n div[active] {\n background-color: red;\n }\n\n div button {\n position: absolute;\n right: 10px;\n width: 30px;\n min-height: 20px;\n }\n `\n ]\n\n /**\n * `stack`은 stack에 의해 만들어진 층의 배열을 유지한다.\n */\n @property({ type: Array }) stack: { name: string }[] = []\n\n /**\n * `activeIndex`은 현재 active된 층의 인덱스를 유지한다.\n */\n @property({ type: Number }) activeIndex: number = 0\n\n render() {\n const stack = [...this.stack].reverse()\n const length = stack.length\n\n return html`\n <button id=\"add-floor\" @click=${(e: Event) => this._onClickAddFloor(e)}>+</button>\n\n ${stack.map(\n (item, index) => html`\n <div\n ?active=${length - index - 1 == this.activeIndex}\n @click=${(e: Event) => this._onClickToActive(e)}\n idx=${length - index - 1}\n >\n ${item.name} <button @click=${(e: Event) => this._onClickRemoveFloor(e)}>-</button>\n </div>\n `\n )}\n `\n }\n\n _onClickAddFloor(e: Event) {\n this.stack.push({ name: String(this.stack.length + 1) })\n this.requestUpdate()\n }\n\n _onClickToActive(e: Event) {\n const div = e.target as HTMLElement\n if (div.tagName != 'DIV') {\n return\n }\n\n this.activeIndex = Number(div.getAttribute('idx'))\n }\n\n _onClickRemoveFloor(e: Event) {\n const div = (e.target as HTMLElement).parentElement\n\n if (div?.tagName != 'DIV') {\n return\n }\n\n const idx = Number(div.getAttribute('idx'))\n\n this.stack.splice(idx, 1)\n\n if (this.activeIndex == idx) {\n this.activeIndex = 0\n } else if (this.activeIndex >= idx) {\n this.activeIndex--\n } else if (this.activeIndex >= this.stack.length) {\n this.activeIndex = 0\n }\n\n this.requestUpdate()\n }\n}\n"]}
@@ -1 +0,0 @@
1
- export {};
@@ -1,23 +0,0 @@
1
- import { html } from 'lit';
2
- import { expect, fixture } from '@open-wc/testing';
3
- describe('OxInputAngle', () => {
4
- it('has a default title "Hey there" and angle 5', async () => {
5
- const el = await fixture(html `<ox-input-angle></ox-input-angle>`);
6
- expect(el.title).to.equal('Hey there');
7
- expect(el.radian).to.equal(5);
8
- });
9
- it('increases the angle on button click', async () => {
10
- const el = await fixture(html `<ox-input-angle></ox-input-angle>`);
11
- el.shadowRoot.querySelector('button').click();
12
- expect(el.radian).to.equal(6);
13
- });
14
- it('can override the title via attribute', async () => {
15
- const el = await fixture(html `<ox-input-angle title="attribute title"></ox-input-angle>`);
16
- expect(el.title).to.equal('attribute title');
17
- });
18
- it('passes the a11y audit', async () => {
19
- const el = await fixture(html `<ox-input-angle></ox-input-angle>`);
20
- await expect(el).shadowDom.to.be.accessible();
21
- });
22
- });
23
- //# sourceMappingURL=property-angle.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"property-angle.test.js","sourceRoot":"","sources":["../../test/property-angle.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE1B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAIlD,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,EAAE,GAAG,MAAM,OAAO,CAAe,IAAI,CAAA,mCAAmC,CAAC,CAAA;QAE/E,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QACtC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,EAAE,GAAG,MAAM,OAAO,CAAe,IAAI,CAAA,mCAAmC,CAAC,CAAA;QAC/E,EAAE,CAAC,UAAW,CAAC,aAAa,CAAC,QAAQ,CAAE,CAAC,KAAK,EAAE,CAAA;QAE/C,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,EAAE,GAAG,MAAM,OAAO,CAAe,IAAI,CAAA,2DAA2D,CAAC,CAAA;QAEvG,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,EAAE,GAAG,MAAM,OAAO,CAAe,IAAI,CAAA,mCAAmC,CAAC,CAAA;QAE/E,MAAM,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,EAAE,CAAA;IAC/C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import { html } from 'lit'\n\nimport { expect, fixture } from '@open-wc/testing'\n\nimport { OxInputAngle } from '../src/ox-input-angle'\n\ndescribe('OxInputAngle', () => {\n it('has a default title \"Hey there\" and angle 5', async () => {\n const el = await fixture<OxInputAngle>(html`<ox-input-angle></ox-input-angle>`)\n\n expect(el.title).to.equal('Hey there')\n expect(el.radian).to.equal(5)\n })\n\n it('increases the angle on button click', async () => {\n const el = await fixture<OxInputAngle>(html`<ox-input-angle></ox-input-angle>`)\n el.shadowRoot!.querySelector('button')!.click()\n\n expect(el.radian).to.equal(6)\n })\n\n it('can override the title via attribute', async () => {\n const el = await fixture<OxInputAngle>(html`<ox-input-angle title=\"attribute title\"></ox-input-angle>`)\n\n expect(el.title).to.equal('attribute title')\n })\n\n it('passes the a11y audit', async () => {\n const el = await fixture<OxInputAngle>(html`<ox-input-angle></ox-input-angle>`)\n\n await expect(el).shadowDom.to.be.accessible()\n })\n})\n"]}
@@ -1,87 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import { css, html, LitElement, PropertyValues } from 'lit'
6
- import { customElement, property } from 'lit/decorators.js'
7
-
8
- /**
9
- 여러 버튼 중에서 하나만 눌리거나, 모두 눌리지 않은 상태만을 갖는 라디오 형태의 버튼이다.
10
-
11
- Example:
12
-
13
- <ox-buttons-radio @change=${e => this._onChange(e)} value=${value}>
14
- <div data-value="top"></div>
15
- <div data-value="middle"></div>
16
- <div data-value="bottom"></div>
17
- </ox-buttons-radio>
18
- */
19
- @customElement('ox-buttons-radio')
20
- export class PropertyButtonsRadio extends LitElement {
21
- static styles = [
22
- css`
23
- :host {
24
- display: inline-block;
25
- }
26
- `
27
- ]
28
-
29
- /**
30
- * `value`는 버튼의 눌린 상태를 값으로 갖는 속성이다.
31
- */
32
- @property({ type: Object }) value: Object | null = null
33
- @property({ type: Boolean }) mandatory!: boolean
34
-
35
- render() {
36
- return html` <slot @click=${(e: Event) => this._onTapButton(e)}></slot> `
37
- }
38
-
39
- updated(changes: PropertyValues<this>) {
40
- changes.has('value') && this._onValueChanged(this.value)
41
- }
42
-
43
- get buttons() {
44
- return Array.from(this.querySelectorAll('*'))
45
- }
46
-
47
- _onValueChanged(value: Object | null) {
48
- this.buttons.forEach(button => {
49
- if (value === button.getAttribute('data-value')) {
50
- button.setAttribute('active', '')
51
- } else {
52
- button.removeAttribute('active')
53
- }
54
- })
55
- }
56
-
57
- _onTapButton(e: Event) {
58
- var target = e.target as HTMLElement
59
-
60
- while (!target.hasAttribute('data-value') && target !== this) {
61
- target = target.parentElement!
62
- }
63
-
64
- if (target === this) {
65
- return
66
- }
67
-
68
- var old = this.value
69
-
70
- if (!this.mandatory) {
71
- if (!target.getAttribute('active')) {
72
- this.value = target.getAttribute('data-value')
73
- target.setAttribute('active', '')
74
- } else {
75
- this.value = null
76
- target.removeAttribute('active')
77
- }
78
- } else {
79
- this.value = target.getAttribute('data-value')
80
- target.setAttribute('active', '')
81
- }
82
-
83
- if (old !== this.value) {
84
- this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
85
- }
86
- }
87
- }
@@ -1,141 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- /*
6
- This component is inspired by https://github.com/Polydile/dile-components, thanks Dile.
7
- */
8
-
9
- import { css, html, LitElement } from 'lit'
10
- import { customElement, property, state } from 'lit/decorators.js'
11
-
12
- @customElement('ox-checkbox')
13
- export class OxCheckbox extends LitElement {
14
- static styles = [
15
- css`
16
- :host {
17
- display: block;
18
- }
19
-
20
- div {
21
- display: flex;
22
- align-items: center;
23
- cursor: pointer;
24
- }
25
-
26
- [disabled] {
27
- opacity: var(--ox-checkbox-disabled-opacity, 0.5);
28
- cursor: auto;
29
- }
30
-
31
- [checkbox] {
32
- display: flex;
33
- border-radius: var(--ox-checkbox-border-radius, 4px);
34
- border: var(--ox-checkbox-border, 1px solid rgba(0, 0, 0, 0.3));
35
- background-color: var(--ox-checkbox-background-color, #fff);
36
- width: var(--ox-checkbox-size, 18px);
37
- height: var(--ox-checkbox-size, 18px);
38
- align-items: center;
39
- justify-content: center;
40
- }
41
-
42
- a {
43
- background-color: var(--ox-checkbox-unchecked-background-color, #fff);
44
- border: var(--ox-checkbox-unchecked-border, 1px solid rgba(0, 0, 0, 0.3));
45
- }
46
-
47
- a[checked] {
48
- background-color: var(--ox-checkbox-checked-background-color, #fff);
49
- border: var(--ox-checkbox-checked-border, 1px solid #38a25b);
50
- }
51
-
52
- path {
53
- fill: var(--ox-checkbox-fill-color, rgba(0, 0, 0, 0.1));
54
- }
55
-
56
- [checked] path {
57
- fill: var(--ox-checkbox-checked-color, #38a25b);
58
- }
59
-
60
- svg {
61
- width: var(--ox-checkbox-size, 18px);
62
- height: var(--ox-checkbox-size, 18px);
63
- }
64
-
65
- [label] {
66
- margin: var(--ox-checkbox-label-margin, 0 0 0 7px);
67
- color: var(--ox-checkbox-label-color, #3a5877);
68
- }
69
-
70
- [checked] + [label] {
71
- font-weight: var(--ox-checkbox-checked-font-weight, bold);
72
- }
73
- `
74
- ]
75
-
76
- @property({ type: Boolean }) checked: boolean = false
77
- @property({ type: Boolean }) disabled: boolean = false
78
- @property({ type: String }) name: string = ''
79
-
80
- @state() _hasInner: boolean = !!this.innerHTML.trim().length
81
-
82
- render() {
83
- return html`
84
- <div @click=${this.onClick} ?disabled=${this.disabled}>
85
- <a
86
- href="#"
87
- @click=${(e: Event) => e.preventDefault()}
88
- @keydown=${this.onKeyDown}
89
- ?checked=${this.checked}
90
- checkbox
91
- >
92
- ${this.checked ? this.checkedIcon : this.uncheckedIcon}
93
- </a>
94
- ${this._hasInner
95
- ? html` <span label>
96
- <slot></slot>
97
- </span>`
98
- : ''}
99
- </div>
100
- `
101
- }
102
-
103
- onClick() {
104
- if (this.disabled) {
105
- return
106
- }
107
-
108
- this.checked = !this.checked
109
-
110
- this.dispatchEvent(
111
- new CustomEvent('change', {
112
- bubbles: true,
113
- composed: true,
114
- detail: {
115
- checked: this.checked,
116
- name: this.name
117
- }
118
- })
119
- )
120
- }
121
-
122
- get checkedIcon() {
123
- return html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
124
- <path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />
125
- </svg>`
126
- }
127
-
128
- get uncheckedIcon() {
129
- return html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
130
- <path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />
131
- </svg>`
132
- }
133
-
134
- onKeyDown(e: KeyboardEvent) {
135
- e.preventDefault()
136
-
137
- if (e.keyCode == 32 || e.code == 'Space') {
138
- this.onClick()
139
- }
140
- }
141
- }
@@ -1,150 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import { css, html, LitElement } from 'lit'
6
- import { customElement, property } from 'lit/decorators.js'
7
-
8
- import { OxInputAngle } from './ox-input-angle'
9
-
10
- @customElement('ox-input-3dish')
11
- export class OxInput3Dish extends LitElement {
12
- static styles = [
13
- css`
14
- :host {
15
- display: grid;
16
- grid-template-columns: repeat(4, minmax(50px, 1fr));
17
- grid-gap: 5px;
18
- grid-auto-rows: minmax(24px, auto);
19
- }
20
-
21
- :host > * {
22
- grid-column: span 1;
23
- }
24
-
25
- label {
26
- text-align: right;
27
- }
28
-
29
- span {
30
- text-align: center;
31
- }
32
- `
33
- ]
34
-
35
- @property({ type: Object }) dimension?: { width: number; height: number; depth: number }
36
- /*
37
- * translate는 고유한 html element의 attribute이므로, property는 translatex로 한다.
38
- */
39
- @property({ type: Object }) translatex?: { x: number; y: number; z: number }
40
- @property({ type: Object }) rotate?: { x: number; y: number; z: number }
41
- @property({ type: Object }) scale?: { x: number; y: number; z: number }
42
-
43
- firstUpdated() {
44
- this.renderRoot.addEventListener('change', this._onChange.bind(this))
45
- }
46
-
47
- _onChange(e: Event) {
48
- var element = e.target as HTMLElement
49
- var id = element.id
50
- var prop = id.substr(1)
51
- var value = Number((element as HTMLInputElement).value)
52
-
53
- switch (element.tagName) {
54
- case 'PROPERTY-ANGLE':
55
- value = Number((element as OxInputAngle).radian || 0)
56
- break
57
- }
58
-
59
- switch (id) {
60
- case 'tx':
61
- case 'ty':
62
- case 'tz':
63
- this.dispatchEvent(
64
- new CustomEvent('translate-changed', {
65
- bubbles: true,
66
- composed: true,
67
- detail: {
68
- value: {
69
- ...this.translatex,
70
- [prop]: value
71
- }
72
- }
73
- })
74
- )
75
- break
76
-
77
- case 'rx':
78
- case 'ry':
79
- case 'rz':
80
- this.dispatchEvent(
81
- new CustomEvent('rotate-changed', {
82
- bubbles: true,
83
- composed: true,
84
- detail: {
85
- value: {
86
- ...this.rotate,
87
- [prop]: value
88
- }
89
- }
90
- })
91
- )
92
- break
93
-
94
- case 'sx':
95
- case 'sy':
96
- case 'sz':
97
- this.dispatchEvent(
98
- new CustomEvent('scale-changed', {
99
- bubbles: true,
100
- composed: true,
101
- detail: {
102
- value: {
103
- ...this.scale,
104
- [prop]: value
105
- }
106
- }
107
- })
108
- )
109
- break
110
-
111
- default:
112
- // dimension
113
- this.dispatchEvent(
114
- new CustomEvent('dimension-changed', {
115
- bubbles: true,
116
- composed: true,
117
- detail: {
118
- value: {
119
- ...this.dimension,
120
- [prop]: value
121
- }
122
- }
123
- })
124
- )
125
- }
126
- }
127
-
128
- render() {
129
- return html`
130
- <span></span> <span><i18n-msg msgid="label.x-axes">x-axes</i18n-msg></span>
131
- <span><i18n-msg msgid="label.y-axes">y-axes</i18n-msg></span>
132
- <span><i18n-msg msgid="label.z-axes">z-axes</i18n-msg></span>
133
-
134
- <label><i18n-msg msgid="label.dimension">dimension</i18n-msg></label>
135
- <input type="number" id="dwidth" .value=${this.dimension?.width} />
136
- <input type="number" id="dheight" .value=${this.dimension?.height} />
137
- <input type="number" id="ddepth" .value=${this.dimension?.depth} />
138
-
139
- <label><i18n-msg msgid="label.translate">translate</i18n-msg></label>
140
- <input type="number" id="tx" .value=${this.translatex?.x} />
141
- <input type="number" id="ty" .value=${this.translatex?.y} />
142
- <input type="number" id="tz" .value=${this.translatex?.z} />
143
-
144
- <label><i18n-msg msgid="label.rotate">rotate</i18n-msg></label>
145
- <ox-input-angle id="rx" .radian=${this.rotate?.x}></ox-input-angle>
146
- <ox-input-angle id="ry" .radian=${this.rotate?.y}></ox-input-angle>
147
- <ox-input-angle id="rz" .radian=${this.rotate?.z}></ox-input-angle>
148
- `
149
- }
150
- }
@@ -1,56 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import { css, html, LitElement } from 'lit'
6
- import { customElement, property, query } from 'lit/decorators.js'
7
-
8
- @customElement('ox-input-angle')
9
- export class OxInputAngle extends LitElement {
10
- static styles = [
11
- css`
12
- :host {
13
- display: inline-block;
14
- }
15
-
16
- input {
17
- width: 100%;
18
- height: 100%;
19
- box-sizing: border-box;
20
- border: 1px solid rgba(0, 0, 0, 0.2);
21
- }
22
- `
23
- ]
24
-
25
- @property({ type: Number }) radian?: string | number
26
- @query('input') input!: HTMLInputElement
27
-
28
- render() {
29
- return html`
30
- <input
31
- type="number"
32
- .value=${this._toDegree(this.radian)}
33
- @change=${(e: Event) => this._onChangeValue(e)}
34
- .placeholder=${this.placeholder}
35
- />
36
- `
37
- }
38
-
39
- get placeholder() {
40
- return this.getAttribute('placeholder') || '0°'
41
- }
42
-
43
- _onChangeValue(e: Event) {
44
- this.radian = this._toRadian(this.input.value)
45
-
46
- this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
47
- }
48
-
49
- _toDegree(radian: string | number | undefined) {
50
- return Math.round(((Number(radian) || 0) * 180) / Math.PI)
51
- }
52
-
53
- _toRadian(degree: string | number | undefined) {
54
- return isNaN(Number(degree)) ? undefined : Number(degree) * (Math.PI / 180)
55
- }
56
- }
@@ -1,109 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import { css, html, LitElement } from 'lit'
6
- import { customElement, property } from 'lit/decorators.js'
7
-
8
- @customElement('ox-stack')
9
- export default class OxStack extends LitElement {
10
- static styles = [
11
- css`
12
- :host {
13
- display: block;
14
- }
15
-
16
- #add-floor {
17
- width: 100%;
18
- height: 20px;
19
- background-color: blue;
20
- color: white;
21
- }
22
-
23
- div {
24
- background-color: blue;
25
- width: calc(100% - 40px);
26
- width: -webkit-calc(100% - 40px);
27
- min-height: 20px;
28
- }
29
-
30
- div[active] {
31
- background-color: red;
32
- }
33
-
34
- div button {
35
- position: absolute;
36
- right: 10px;
37
- width: 30px;
38
- min-height: 20px;
39
- }
40
- `
41
- ]
42
-
43
- /**
44
- * `stack`은 stack에 의해 만들어진 층의 배열을 유지한다.
45
- */
46
- @property({ type: Array }) stack: { name: string }[] = []
47
-
48
- /**
49
- * `activeIndex`은 현재 active된 층의 인덱스를 유지한다.
50
- */
51
- @property({ type: Number }) activeIndex: number = 0
52
-
53
- render() {
54
- const stack = [...this.stack].reverse()
55
- const length = stack.length
56
-
57
- return html`
58
- <button id="add-floor" @click=${(e: Event) => this._onClickAddFloor(e)}>+</button>
59
-
60
- ${stack.map(
61
- (item, index) => html`
62
- <div
63
- ?active=${length - index - 1 == this.activeIndex}
64
- @click=${(e: Event) => this._onClickToActive(e)}
65
- idx=${length - index - 1}
66
- >
67
- ${item.name} <button @click=${(e: Event) => this._onClickRemoveFloor(e)}>-</button>
68
- </div>
69
- `
70
- )}
71
- `
72
- }
73
-
74
- _onClickAddFloor(e: Event) {
75
- this.stack.push({ name: String(this.stack.length + 1) })
76
- this.requestUpdate()
77
- }
78
-
79
- _onClickToActive(e: Event) {
80
- const div = e.target as HTMLElement
81
- if (div.tagName != 'DIV') {
82
- return
83
- }
84
-
85
- this.activeIndex = Number(div.getAttribute('idx'))
86
- }
87
-
88
- _onClickRemoveFloor(e: Event) {
89
- const div = (e.target as HTMLElement).parentElement
90
-
91
- if (div?.tagName != 'DIV') {
92
- return
93
- }
94
-
95
- const idx = Number(div.getAttribute('idx'))
96
-
97
- this.stack.splice(idx, 1)
98
-
99
- if (this.activeIndex == idx) {
100
- this.activeIndex = 0
101
- } else if (this.activeIndex >= idx) {
102
- this.activeIndex--
103
- } else if (this.activeIndex >= this.stack.length) {
104
- this.activeIndex = 0
105
- }
106
-
107
- this.requestUpdate()
108
- }
109
- }
@@ -1,33 +0,0 @@
1
- import { html } from 'lit'
2
-
3
- import { expect, fixture } from '@open-wc/testing'
4
-
5
- import { OxInputAngle } from '../src/ox-input-angle'
6
-
7
- describe('OxInputAngle', () => {
8
- it('has a default title "Hey there" and angle 5', async () => {
9
- const el = await fixture<OxInputAngle>(html`<ox-input-angle></ox-input-angle>`)
10
-
11
- expect(el.title).to.equal('Hey there')
12
- expect(el.radian).to.equal(5)
13
- })
14
-
15
- it('increases the angle on button click', async () => {
16
- const el = await fixture<OxInputAngle>(html`<ox-input-angle></ox-input-angle>`)
17
- el.shadowRoot!.querySelector('button')!.click()
18
-
19
- expect(el.radian).to.equal(6)
20
- })
21
-
22
- it('can override the title via attribute', async () => {
23
- const el = await fixture<OxInputAngle>(html`<ox-input-angle title="attribute title"></ox-input-angle>`)
24
-
25
- expect(el.title).to.equal('attribute title')
26
- })
27
-
28
- it('passes the a11y audit', async () => {
29
- const el = await fixture<OxInputAngle>(html`<ox-input-angle></ox-input-angle>`)
30
-
31
- await expect(el).shadowDom.to.be.accessible()
32
- })
33
- })