kempo-ui 0.0.3 → 0.0.4

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 (137) hide show
  1. package/.github/workflows/publish-major.yml +39 -0
  2. package/.github/workflows/publish-minor.yml +39 -0
  3. package/.github/workflows/{publish-npm.yml → publish-patch.yml} +1 -1
  4. package/.vscode/settings.json +2 -0
  5. package/dist/kempo-hljs.css +1 -0
  6. package/dist/src/components/Accordion.js +36 -0
  7. package/dist/src/components/Card.js +37 -0
  8. package/dist/src/components/Collapsible.js +41 -0
  9. package/dist/src/components/ContentSlider.js +44 -0
  10. package/dist/src/components/Dialog.js +113 -0
  11. package/dist/src/components/Icon.js +2 -2
  12. package/dist/src/components/PersistantCollapsible.js +1 -0
  13. package/dist/src/components/PhotoViewer.js +135 -0
  14. package/dist/src/components/Resize.js +96 -0
  15. package/dist/src/components/ShowMore.js +42 -0
  16. package/dist/src/components/SideMenu.js +1 -1
  17. package/dist/src/components/Split.js +84 -0
  18. package/dist/src/components/Tabs.js +155 -0
  19. package/dist/src/components/Tags.js +69 -0
  20. package/dist/src/components/ThemeSwitcher.js +23 -0
  21. package/dist/src/components/Timestamp.js +1 -0
  22. package/dist/src/utils/debounce.js +1 -0
  23. package/dist/src/utils/drag.js +1 -0
  24. package/dist/src/utils/formatTimestamp.js +1 -0
  25. package/dist/src/utils/propConverters.js +1 -0
  26. package/dist/src/utils/watchWindowSize.js +1 -0
  27. package/docs/components/accordion.html +69 -25
  28. package/docs/components/card.html +6 -5
  29. package/docs/components/collapsible.html +198 -0
  30. package/docs/components/content-slider.html +56 -26
  31. package/docs/components/dialog.html +54 -48
  32. package/docs/components/focus-capture.html +2 -3
  33. package/docs/components/icon.html +5 -8
  34. package/docs/components/import.html +1 -6
  35. package/docs/components/persistant-collapsible.html +123 -0
  36. package/docs/components/photo-viewer.html +226 -0
  37. package/docs/components/resize.html +44 -18
  38. package/docs/components/show-more.html +12 -6
  39. package/docs/components/side-menu.html +3 -12
  40. package/docs/components/split.html +26 -5
  41. package/docs/components/tablePagination.html +4 -4
  42. package/docs/components/tableRecordFiltering.html +16 -3
  43. package/docs/components/tableRecordSelection.html +2 -2
  44. package/docs/components/tabs.html +24 -7
  45. package/docs/components/tags.html +24 -8
  46. package/docs/components/theme-switcher.html +3 -6
  47. package/docs/components/timestamp.html +20 -24
  48. package/docs/components/toast.html +23 -32
  49. package/docs/components/toggle.html +4 -3
  50. package/docs/kempo-hljs.css +1 -0
  51. package/docs/media/civic.jpg +0 -0
  52. package/docs/media/corvette.jpg +0 -0
  53. package/docs/media/evo.jpg +0 -0
  54. package/docs/media/gtr.jpg +0 -0
  55. package/docs/media/nsx.jpg +0 -0
  56. package/docs/nav.inc.html +11 -17
  57. package/docs/src/components/Accordion.js +36 -0
  58. package/docs/src/components/Card.js +37 -0
  59. package/docs/src/components/Collapsible.js +41 -0
  60. package/docs/src/components/ContentSlider.js +44 -0
  61. package/docs/src/components/Dialog.js +113 -0
  62. package/docs/src/components/Icon.js +2 -2
  63. package/docs/src/components/PersistantCollapsible.js +1 -0
  64. package/docs/src/components/PhotoViewer.js +135 -0
  65. package/docs/src/components/Resize.js +96 -0
  66. package/docs/src/components/ShowMore.js +42 -0
  67. package/docs/src/components/SideMenu.js +1 -1
  68. package/docs/src/components/Split.js +84 -0
  69. package/docs/src/components/Tabs.js +155 -0
  70. package/docs/src/components/Tags.js +69 -0
  71. package/docs/src/components/ThemeSwitcher.js +23 -0
  72. package/docs/src/components/Timestamp.js +1 -0
  73. package/docs/src/utils/debounce.js +1 -0
  74. package/docs/src/utils/drag.js +1 -0
  75. package/docs/src/utils/formatTimestamp.js +1 -0
  76. package/docs/src/utils/propConverters.js +1 -0
  77. package/docs/src/utils/watchWindowSize.js +1 -0
  78. package/docs/utils/debounce.html +78 -0
  79. package/docs/utils/drag.html +104 -0
  80. package/docs/utils/formatTimestamp.html +114 -0
  81. package/docs/utils/propConverters.html +132 -0
  82. package/docs/utils/watchWindowSize.html +166 -0
  83. package/icons/error.svg +1 -1
  84. package/icons/warning.svg +1 -1
  85. package/package.json +1 -1
  86. package/scripts/build.js +1 -1
  87. package/scripts/docs.js +4 -2
  88. package/src/components/Accordion.js +229 -0
  89. package/src/components/Collapsible.js +109 -0
  90. package/src/components/ContentSlider.js +205 -0
  91. package/src/components/Dialog.js +368 -0
  92. package/src/components/PersistantCollapsible.js +69 -0
  93. package/src/components/PhotoViewer.js +368 -0
  94. package/src/components/Resize.js +210 -0
  95. package/src/components/ShadowComponent.js +3 -1
  96. package/src/components/ShowMore.js +109 -0
  97. package/src/components/Sortable.js +193 -0
  98. package/src/components/Split.js +192 -0
  99. package/src/components/Table.js +1202 -0
  100. package/src/components/Tabs.js +428 -0
  101. package/src/components/Tags.js +253 -0
  102. package/src/components/Timestamp.js +31 -0
  103. package/src/components/Toast.js +454 -0
  104. package/src/components/Toggle.js +173 -0
  105. package/src/components/tableControls/DeleteRecord.js +29 -0
  106. package/src/components/tableControls/Edit.js +88 -0
  107. package/src/components/tableControls/ExportCSV.js +71 -0
  108. package/src/components/tableControls/ExportJson.js +55 -0
  109. package/src/components/tableControls/FieldSortHide.js +76 -0
  110. package/src/components/tableControls/Filters.js +114 -0
  111. package/src/components/tableControls/FirstPage.js +65 -0
  112. package/src/components/tableControls/HiddenCount.js +45 -0
  113. package/src/components/tableControls/Hide.js +34 -0
  114. package/src/components/tableControls/LastPage.js +65 -0
  115. package/src/components/tableControls/NextPage.js +65 -0
  116. package/src/components/tableControls/PageSelect.js +109 -0
  117. package/src/components/tableControls/PageSize.js +68 -0
  118. package/src/components/tableControls/PrevPage.js +65 -0
  119. package/src/components/tableControls/Search.js +58 -0
  120. package/src/components/tableControls/ShowAll.js +34 -0
  121. package/src/components/tableControls/TableControl.js +105 -0
  122. package/src/utils/debounce.js +9 -0
  123. package/src/utils/drag.js +80 -0
  124. package/src/utils/formatTimestamp.js +27 -0
  125. package/src/utils/toTitleCase.js +9 -0
  126. package/src/utils/watchWindowSize.js +16 -0
  127. package/dist/src/utils/cli.js +0 -1
  128. package/dist/src/utils/fs-utils.js +0 -1
  129. package/docs/components/component.html +0 -90
  130. package/docs/components/directory-viewer.html +0 -90
  131. package/docs/components/lazy-component.html +0 -84
  132. package/docs/components/reactive-component.html +0 -69
  133. package/docs/components/reactive-lazy-component.html +0 -69
  134. package/docs/components/search.html +0 -102
  135. package/docs/components/sortable.html +0 -96
  136. package/src/utils/cli.js +0 -43
  137. package/src/utils/fs-utils.js +0 -41
@@ -0,0 +1,39 @@
1
+ name: Publish Major Version to npmjs
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ jobs:
7
+ publish:
8
+ runs-on: ubuntu-latest
9
+ permissions:
10
+ contents: write
11
+ id-token: write # enables npm provenance
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ with:
15
+ token: ${{ secrets.GITHUB_TOKEN }}
16
+
17
+ # Setup Node and create an .npmrc that uses the token from NODE_AUTH_TOKEN
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: '20.x'
21
+ registry-url: 'https://registry.npmjs.org'
22
+
23
+ - run: npm ci
24
+
25
+ # Auto-increment major version, commit, and push
26
+ - name: Bump major version
27
+ run: |
28
+ git config --global user.name "github-actions"
29
+ git config --global user.email "github-actions@github.com"
30
+ npm version major --no-git-tag-version
31
+ git add package.json package-lock.json || true
32
+ git commit -m "ci: bump major version [skip ci]" || echo "No changes to commit"
33
+ git push origin HEAD:main || echo "No changes to push"
34
+ env:
35
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36
+
37
+ - run: npm publish --provenance --access public
38
+ env:
39
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,39 @@
1
+ name: Publish Minor Version to npmjs
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ jobs:
7
+ publish:
8
+ runs-on: ubuntu-latest
9
+ permissions:
10
+ contents: write
11
+ id-token: write # enables npm provenance
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ with:
15
+ token: ${{ secrets.GITHUB_TOKEN }}
16
+
17
+ # Setup Node and create an .npmrc that uses the token from NODE_AUTH_TOKEN
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: '20.x'
21
+ registry-url: 'https://registry.npmjs.org'
22
+
23
+ - run: npm ci
24
+
25
+ # Auto-increment minor version, commit, and push
26
+ - name: Bump minor version
27
+ run: |
28
+ git config --global user.name "github-actions"
29
+ git config --global user.email "github-actions@github.com"
30
+ npm version minor --no-git-tag-version
31
+ git add package.json package-lock.json || true
32
+ git commit -m "ci: bump minor version [skip ci]" || echo "No changes to commit"
33
+ git push origin HEAD:main || echo "No changes to push"
34
+ env:
35
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36
+
37
+ - run: npm publish --provenance --access public
38
+ env:
39
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -1,5 +1,5 @@
1
1
 
2
- name: Publish Package to npmjs
2
+ name: Publish Patch Version to npmjs
3
3
 
4
4
  on:
5
5
  push:
@@ -0,0 +1,2 @@
1
+ {
2
+ }
@@ -0,0 +1 @@
1
+ :root,[theme="light"]{--c_text:#000000;--c_keyword:#0000ff;--c_builtin:#00b0e8;--c_number:#709756;--c_string:#a31515;--c_regex:#914525;--c_function:inherit;--c_comment:#008000;--c_doc:#808080;--c_tag:#7d7d7d;--c_var:#b436bf;--c_attr:#ff0000;--c_section:#a31515;--c_selector:#0000ff;--c_addition:#a31515;--c_deletion:#2b91af;--c_caret:black}[auto-theme="dark"]:not([theme="light"]),[theme="dark"]{--c_text:#DCDCDC;--c_keyword:#569CD6;--c_builtin:#4EC9B0;--c_number:#B8D7A3;--c_string:#D69D85;--c_regex:#9A5334;--c_function:inehrit;--c_comment:#57A64A;--c_doc:#608B4E;--c_tag:#9B9B9B;--c_var:#BD63C5;--c_attr:#9CDCFE;--c_section:#ffd700;--c_selector:#569CD6;--c_addition:#144212;--c_deletion:#600;--c_caret:white}.hljs{display:block;overflow-x:auto;color:var(--c_text)}.hljs-keyword,.hljs-literal,.hljs-symbol,.hljs-name,.hljs-link{color:var(--c_keyword)}.hljs-link{text-decoration:underline}.hljs-built_in,.hljs-type{color:var(--c_builtin)}.hljs-number,.hljs-class{color:var(--c_number)}.hljs-string,.hljs-meta-string{color:var(--c_string)}.hljs-regexp,.hljs-template-tag{color:var(--c_regex)}.hljs-subst,.hljs-function,.hljs-title,.hljs-params,.hljs-formula{color:var(--c_function)}.hljs-comment,.hljs-quote{color:var(--c_comment);font-style:italic}.hljs-doctag{color:var(--c_doc)}.hljs-meta,.hljs-meta-keyword,.hljs-tag{color:var(--c_tag)}.hljs-variable,.hljs-template-variable{color:var(--c_var)}.hljs-attr,.hljs-attribute,.hljs-builtin-name{color:var(--c_attr)}.hljs-section{color:var(--c_section)}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}.hljs-bullet,.hljs-selector-tag,.hljs-selector-id,.hljs-selector-class,.hljs-selector-attr,.hljs-selector-pseudo{color:var(--c_selector)}.hljs-addition{background-color:var(--c_addition);display:inline-block;width:100%}.hljs-deletion{background-color:var(--c_deletion);display:inline-block;width:100%}
@@ -0,0 +1,36 @@
1
+ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";import{boolTrueFalse}from"../utils/propConverters.js";export default class Accordion extends ShadowComponent{static properties={};getHeader(e){return this.querySelector(`k-accordion-header[for-panel="${e}"]`)}getPanel(e){return this.querySelector(`k-accordion-panel[name="${e}"]`)}openPanel(e){const t=this.querySelector('k-accordion-panel[active="true"]');if(t&&t.name!==e){t.active=!1;const e=this.getHeader(t.name);e&&(e.active=!1)}const o=this.getPanel(e);if(o){o.active=!0,o.transitioning=!0,setTimeout(()=>{o.transitioning=!1},parseInt(getComputedStyle(this).getPropertyValue("--animation_ms")||256));const t=this.getHeader(e);t&&(t.active=!0),this.dispatchEvent(new CustomEvent("openpanel",{detail:{panelName:e}}))}}closePanel(e){const t=this.getPanel(e);if(t){t.active=!1,t.transitioning=!0,setTimeout(()=>{t.transitioning=!1},parseInt(getComputedStyle(this).getPropertyValue("--animation_ms")||256));const o=this.getHeader(e);o&&(o.active=!1),this.dispatchEvent(new CustomEvent("closepanel",{detail:{panelName:e}}))}}togglePanel(e){const t=this.getPanel(e);t&&(t.active?this.closePanel(e):this.openPanel(e),this.dispatchEvent(new CustomEvent("togglepanel",{detail:{panelName:e}})))}get activeHeader(){return this.querySelector('k-accordion-header[active="true"]')}get activePanel(){return this.querySelector('k-accordion-panel[active="true"]')}static styles=css`
2
+ :host {
3
+ display: block;
4
+ border: 1px solid var(--c_border);
5
+ border-radius: var(--radius);
6
+ }
7
+ ::slotted(k-accordion-header) {
8
+ border-top: 1px solid var(--c_border);
9
+ }
10
+ ::slotted(k-accordion-header[active="true"]) {
11
+ border-bottom: 1px solid var(--c_border);
12
+ }
13
+ ::slotted(k-accordion-header:first-of-type) {
14
+ border-top: 0;
15
+ }
16
+ ::slotted(k-accordion-header:last-of-type:not([active="true"])) {
17
+ border-bottom: 0;
18
+ }
19
+ `;render(){return html`<slot></slot>`}}export class AccordionHeader extends ShadowComponent{static properties={forPanel:{type:String,reflect:!0,attribute:"for-panel"},active:{type:Boolean,reflect:!0,converter:boolTrueFalse}};constructor(){super(),this.forPanel="",this.active=!1}handleClick=()=>{this.accordion?.togglePanel(this.forPanel)};connectedCallback(){super.connectedCallback(),this.addEventListener("click",this.handleClick)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("click",this.handleClick)}get accordion(){return this.closest("k-accordion")}static styles=css`
20
+ :host {
21
+ display: block;
22
+ padding: 1rem;
23
+ cursor: pointer;
24
+ }
25
+ `;render(){return html`<slot></slot>`}}export class AccordionPanel extends ShadowComponent{static properties={name:{type:String,reflect:!0},active:{type:Boolean,reflect:!0,converter:boolTrueFalse},transitioning:{type:Boolean,reflect:!0,converter:boolTrueFalse}};constructor(){super(),this.name="",this.active=!1,this.transitioning=!1}get accordion(){return this.closest("k-accordion")}static styles=css`
26
+ :host {
27
+ display: block;
28
+ interpolate-size: allow-keywords;
29
+ height: 0;
30
+ overflow: hidden;
31
+ transition: height var(--animation_ms, 256ms) ease-in-out;
32
+ }
33
+ :host([active="true"]) {
34
+ height: max-content;
35
+ }
36
+ `;render(){return html`<slot></slot>`}}customElements.define("k-accordion",Accordion),customElements.define("k-accordion-header",AccordionHeader),customElements.define("k-accordion-panel",AccordionPanel);
@@ -0,0 +1,37 @@
1
+ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";export default class Card extends ShadowComponent{static properties={label:{type:String,reflect:!0}};constructor(){super(),this.label=""}static styles=css`
2
+ :host {
3
+ display: block;
4
+ }
5
+ #card {
6
+ border: 1px solid var(--c_border);
7
+ border-radius: var(--radius);
8
+ margin-bottom: var(--spacer);
9
+ padding: var(--spacer);
10
+ position: relative;
11
+ background-color: var(--c_bg);
12
+ }
13
+ #label {
14
+ position: absolute;
15
+ top: -1.25em;
16
+ left: 1.25em;
17
+ background-color: var(--c_bg);
18
+ border: 1px solid var(--c_border);
19
+ border-radius: var(--radius);
20
+ padding: var(--spacer_h);
21
+ }
22
+ :host([label]) {
23
+ padding-top: calc(1.5 * var(--spacer));
24
+ margin-top: var(--spacer);
25
+ }
26
+ :host([label]) #card {
27
+ padding-top: calc(1.5 * var(--spacer));
28
+ }
29
+ :host(:not([label])) #label {
30
+ display: none;
31
+ }
32
+ `;render(){return html`
33
+ <div id="card">
34
+ <div id="label">${this.label}</div>
35
+ <slot></slot>
36
+ </div>
37
+ `}}window.customElements.define("k-card",Card);
@@ -0,0 +1,41 @@
1
+ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";import{boolTrueFalse}from"../utils/propConverters.js";import"./Icon.js";export default class Collapsible extends ShadowComponent{static properties={opened:{type:Boolean,reflect:!0,converter:boolTrueFalse}};constructor(){super(),this.opened=!1}handleLabelClick=()=>{this.toggle()};updated(e){super.updated(e),e.has("opened")&&(this.dispatchEvent(new CustomEvent("openedchanged",{detail:this.opened?"open":"close"})),this.dispatchEvent(new CustomEvent(this.opened?"open":"close")))}open(){this.opened=!0}close(){this.opened=!1}toggle(){this.opened=!this.opened,this.dispatchEvent(new CustomEvent("openedtoggled"))}static styles=css`
2
+ :host {
3
+ display: block;
4
+ }
5
+ #labelContainer {
6
+ display: flex;
7
+ cursor: pointer;
8
+ }
9
+ #label {
10
+ flex: 1 1 auto;
11
+ }
12
+ #labelIcon {
13
+ flex: 0 0 none;
14
+ opacity: 0.5;
15
+ transform: rotate(90deg);
16
+ transition: transform var(--animation_ms, 256ms);
17
+ }
18
+ #labelContainer:hover #labelIcon {
19
+ opacity: 1;
20
+ }
21
+ :host([opened="true"]) #labelIcon {
22
+ transform: rotate(-90deg);
23
+ }
24
+ :host(:not([opened="true"])) #content {
25
+ display: none;
26
+ }
27
+ `;render(){return html`
28
+ <div id="labelContainer" @click=${this.handleLabelClick}>
29
+ <div id="label">
30
+ <slot name="label"></slot>
31
+ </div>
32
+ <div id="labelIcon">
33
+ <slot name="labelIcon">
34
+ <k-icon name="chevron-right"></k-icon>
35
+ </slot>
36
+ </div>
37
+ </div>
38
+ <div id="content">
39
+ <slot></slot>
40
+ </div>
41
+ `}}customElements.define("k-collapsible",Collapsible);
@@ -0,0 +1,44 @@
1
+ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";import{boolTrueFalse}from"../utils/propConverters.js";import"./Icon.js";export default class ContentSlider extends ShadowComponent{static properties={index:{type:Number,reflect:!0},controls:{type:Boolean,reflect:!0,converter:boolTrueFalse},globalControls:{type:Boolean,reflect:!0,attribute:"global-controls",converter:boolTrueFalse},keyboardControls:{type:Boolean,reflect:!0,attribute:"keyboard-controls",converter:boolTrueFalse},loop:{type:Boolean,reflect:!0,converter:boolTrueFalse}};constructor(){super(),this.index=0,this.controls=!0,this.globalControls=!1,this.keyboardControls=!0,this.loop=!1,this.content=[],this.tabIndex=0}handlePrevClick=()=>{this.previous()};handleNextClick=()=>{this.next()};handleKeydown=t=>{"ArrowLeft"===t.code?(t.preventDefault(),this.dispatchEvent(new CustomEvent("keyleft")),this.previous()):"ArrowRight"===t.code&&(t.preventDefault(),this.dispatchEvent(new CustomEvent("keyright")),this.next())};connectedCallback(){super.connectedCallback(),this.updateContent(),this.setupKeyboardControls()}disconnectedCallback(){super.disconnectedCallback(),this.removeKeyboardControls()}updated(t){super.updated(t),t.has("index")&&(this.validateAndSetIndex(),this.renderContent(),this.dispatchEvent(new CustomEvent("change",{detail:{index:this.index}}))),(t.has("keyboardControls")||t.has("globalControls"))&&(this.removeKeyboardControls(),this.setupKeyboardControls())}updateContent(){this.content=[...this.querySelectorAll(":scope > *")],this.validateAndSetIndex(),this.renderContent()}validateAndSetIndex(){if(0===this.content.length)return;const t=Math.max(Math.min(this.content.length-1,this.index),0);this.index!==t&&(this.index=t)}renderContent(){0!==this.content.length&&(this.innerHTML="",this.content[this.index]&&this.appendChild(this.content[this.index]))}setupKeyboardControls(){this.keyboardControls&&(this.globalControls?window.addEventListener("keydown",this.handleKeydown):this.addEventListener("keydown",this.handleKeydown))}removeKeyboardControls(){window.removeEventListener("keydown",this.handleKeydown),this.removeEventListener("keydown",this.handleKeydown)}previous(){let t=this.index-1;this.loop&&t<0&&(t=this.content.length-1),this.dispatchEvent(new CustomEvent("previous",{detail:{index:t}})),this.index=t}next(){let t=this.index+1;this.loop&&t>=this.content.length&&(t=0),this.dispatchEvent(new CustomEvent("next",{detail:{index:t}})),this.index=t}goto(t){this.dispatchEvent(new CustomEvent("goto",{detail:{index:t}})),this.index=t}static styles=css`
2
+ :host {
3
+ display: block;
4
+ position: relative;
5
+ outline: none;
6
+ }
7
+ #prev,
8
+ #next {
9
+ position: absolute;
10
+ top: 50%;
11
+ transform: translateY(-50%);
12
+ font-size: 2rem;
13
+ }
14
+ #next {
15
+ right: 0;
16
+ }
17
+ :host(:not([controls="true"])) #controls {
18
+ display: none;
19
+ }
20
+ `;render(){return html`
21
+ <div id="content">
22
+ <slot></slot>
23
+ </div>
24
+ <div id="controls">
25
+ <button
26
+ id="prev"
27
+ class="no-btn"
28
+ @click=${this.handlePrevClick}
29
+ >
30
+ <slot name="prev">
31
+ <k-icon name="chevron-left"></k-icon>
32
+ </slot>
33
+ </button>
34
+ <button
35
+ id="next"
36
+ class="no-btn"
37
+ @click=${this.handleNextClick}
38
+ >
39
+ <slot name="next">
40
+ <k-icon name="chevron-right"></k-icon>
41
+ </slot>
42
+ </button>
43
+ </div>
44
+ `}}customElements.define("k-content-slider",ContentSlider);
@@ -0,0 +1,113 @@
1
+ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";import{boolExists}from"../utils/propConverters.js";import"./Icon.js";const firstFocusable=t=>t.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')[0];export default class Dialog extends ShadowComponent{static properties={opened:{type:Boolean,reflect:!0,converter:boolExists},closeBtn:{type:Boolean,reflect:!0,attribute:"close-btn",converter:boolExists},overlayClose:{type:Boolean,reflect:!0,attribute:"overlay-close",converter:boolExists},confirmText:{type:String,reflect:!0,attribute:"confirm-text"},confirmClasses:{type:String,reflect:!0,attribute:"confirm-classes"},cancelText:{type:String,reflect:!0,attribute:"cancel-text"},cancelClasses:{type:String,reflect:!0,attribute:"cancel-classes"}};constructor(){super(),this.opened=!1,this.closeBtn=!0,this.overlayClose=!0,this.confirmText="",this.confirmClasses="success ml",this.cancelText="",this.cancelClasses="",this.confirmAction=()=>{},this.cancelAction=()=>{},this.closeCallback=()=>{},this.previousFocus=null}handleClick=t=>{const{target:e}=t,o=e.id||e.closest("[id]")?.id;"overlay"===o&&this.overlayClose||"close"===o?this.close():"cancel"===o?(this.cancelAction(t),t.defaultPrevented||this.close()):"confirm"===o&&(this.confirmAction(t),t.defaultPrevented||this.close())};handleKeydown=t=>{27===t.keyCode&&this.close()};connectedCallback(){super.connectedCallback()}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("keydown",this.handleKeydown)}updated(t){super.updated(t),t.has("opened")&&this.dispatchEvent(new CustomEvent(this.opened?"opened":"close"))}open(){this.opened=!0,window.addEventListener("keydown",this.handleKeydown);const t=this.updateComplete||this.requestUpdate();t&&t.then?t.then(()=>{const t=this.shadowRoot.querySelector("[autofocus]")||firstFocusable(this.shadowRoot);t&&t.focus()}):setTimeout(()=>{const t=this.shadowRoot.querySelector("[autofocus]")||firstFocusable(this.shadowRoot);t&&t.focus()},0)}close(){this.opened=!1,this.blur(),this.closeCallback(),window.removeEventListener("keydown",this.handleKeydown)}toggle(){this.opened?this.close():this.open()}focus(){const t=firstFocusable(this.shadowRoot);t&&(this.previousFocus=document.activeElement,t.focus())}blur(){this.previousFocus&&this.previousFocus.focus()}hasTitle(){return!!this.querySelector('[slot="title"]')}static styles=css`
2
+ :host {
3
+ position: fixed;
4
+ top: 0;
5
+ left: 0;
6
+ width: 100vw;
7
+ height: 100vh;
8
+ z-index: 100;
9
+ display: none;
10
+ justify-content: center;
11
+ align-items: center;
12
+ }
13
+ :host([opened]) {
14
+ display: flex;
15
+ }
16
+ #overlay {
17
+ position: absolute;
18
+ width: 100%;
19
+ height: 100%;
20
+ top: 0;
21
+ left: 0;
22
+ background-color: var(--c_overlay);
23
+ border: 0px solid transparent;
24
+ box-shadow: 0 0 0 transparent;
25
+ }
26
+ #wrapper {
27
+ position: relative;
28
+ z-index: 1;
29
+ pointer-events: none;
30
+ }
31
+ #dialog {
32
+ display: flex;
33
+ flex-direction: column;
34
+ min-width: var(--min_width, 20rem);
35
+ width: var(--width, fit-content);
36
+ max-width: var(--max_width, calc(100vw - 4rem));
37
+ min-height: var(--min_height, 12rem);
38
+ height: var(--height, fit-content);
39
+ max-height: var(--max_height, calc(100vh - 4rem));
40
+ background-color: var(--c_bg);
41
+ box-shadow: var(--drop_shadow);
42
+ border-radius: var(--radius);
43
+ pointer-events: all;
44
+ }
45
+ #header {
46
+ display: flex;
47
+ align-items: center;
48
+ }
49
+ #header.has-title {
50
+ border-bottom: 1px solid var(--c_border);
51
+ }
52
+ #title {
53
+ flex: 1 1 auto;
54
+ }
55
+ #close {
56
+ border: 0px;
57
+ background: transparent;
58
+ box-shadow: 0 0 0 transparent;
59
+ color: var(--tc);
60
+ }
61
+ #close k-icon {
62
+ pointer-events: none;
63
+ }
64
+ #body {
65
+ flex: 1 1 auto;
66
+ }
67
+ #footer {
68
+ display: flex;
69
+ justify-content: flex-end;
70
+ padding: var(--spacer_h);
71
+ }
72
+ `;render(){return html`
73
+ <button id="overlay" aria-label="Close the Dialog" @click=${this.handleClick}></button>
74
+ <div id="wrapper">
75
+ <div
76
+ id="dialog"
77
+ role="dialog"
78
+ aria-modal="true"
79
+ aria-labelledby="title"
80
+ >
81
+ <div
82
+ id="header"
83
+ class="${this.hasTitle()?"has-title":""}"
84
+ >
85
+ <div id="title">
86
+ <slot name="title"></slot>
87
+ </div>
88
+ ${this.closeBtn?html`
89
+ <button id="close" @click=${this.handleClick}>
90
+ <k-icon name="close"></k-icon>
91
+ </button>
92
+ `:""}
93
+ </div>
94
+ <div id="body">
95
+ <slot></slot>
96
+ </div>
97
+ ${this.cancelText||this.confirmText?html`
98
+ <div id="footer">
99
+ ${this.cancelText?html`
100
+ <button id="cancel" class="${this.cancelClasses}" @click=${this.handleClick}>
101
+ ${this.cancelText}
102
+ </button>
103
+ `:""}
104
+ ${this.confirmText?html`
105
+ <button id="confirm" class="${this.confirmClasses}" @click=${this.handleClick}>
106
+ ${this.confirmText}
107
+ </button>
108
+ `:""}
109
+ </div>
110
+ `:""}
111
+ </div>
112
+ </div>
113
+ `}static create(t="",e={}){!1!==e.closeExisting&&document.querySelectorAll("k-dialog").forEach(t=>t.close());const{removeOnClose:o=!0,closeCallback:s=()=>{}}=e,i=new Dialog;return Object.assign(i,{opened:!0,...e,closeCallback:(...t)=>{o&&i.remove(),s(...t)}}),t instanceof HTMLElement||t instanceof DocumentFragment?i.appendChild(t):t&&(i.innerHTML=t),e.width&&i.style.setProperty("--width",e.width),e.minWidth&&i.style.setProperty("--min_width",e.minWidth),e.maxWidth&&i.style.setProperty("--max_width",e.maxWidth),e.height&&i.style.setProperty("--height",e.height),e.minHeight&&i.style.setProperty("--min_height",e.minHeight),e.maxHeight&&i.style.setProperty("--max_height",e.maxHeight),document.body.appendChild(i),i.open(),i}static confirm(t,e,o={}){const s=o.title||"Confirm";return Dialog.create(`\n\t\t\t<h5 slot="title" class="pyh px m0">${s}</h5>\n\t\t\t<p class="p">${t}</p>\n\t\t`,{closeBtn:!1,overlayClose:!1,confirmText:"Yes",confirmClasses:"success ml",confirmAction:()=>e(!0),cancelText:"No",cancelClasses:"danger",cancelAction:()=>e(!1),...o})}static alert(t,e,o={}){const s=o.title||"Alert";return Dialog.create(`\n\t\t\t<h5 slot="title" class="pyh px m0">${s}</h5>\n\t\t\t<p class="p">${t}</p>\n\t\t`,{closeCallback:e,cancelText:"Ok",...o})}static error(t,e,o={}){const s=o.title||"Error";return Dialog.create(`\n\t\t\t<h5 slot="title" class="pyh px m0 tc-danger">${s}</h5>\n\t\t\t<p class="p">${t}</p>\n\t\t`,{closeCallback:e,cancelText:"Ok",...o})}static success(t,e,o={}){const s=o.title||"Success";return Dialog.create(`\n\t\t\t<h5 slot="title" class="pyh px m0 tc-success">${s}</h5>\n\t\t\t<p class="p">${t}</p>\n\t\t`,{closeCallback:e,cancelText:"Ok",...o})}}customElements.define("k-dialog",Dialog);
@@ -1,4 +1,4 @@
1
- import ShadowComponent from"./ShadowComponent.js";import{html,css,unsafeHTML}from"../lit-all.min.js";const cache={},getIconByPath=async t=>(cache[t]||(cache[t]=new Promise(async(e,n)=>{const o=(new AbortController).signal;try{const n=await fetch(t,{signal:o});200===n.status?e(await n.text()):404===n.status&&e(null)}catch(t){"AbortError"!==t.name&&n(t)}}).catch(()=>null)),await cache[t]),getIconByName=t=>{const e=async e=>getIconByPath(`${e}/${t}.svg`);return new Promise(async(t,n)=>{let o;for(let t=0;t<Icon.pathToIcons.length&&!o;t++)try{o=await e(Icon.pathToIcons[t])}catch(t){}t(o||null)})};export default class Icon extends ShadowComponent{static properties={src:{type:String,reflect:!0},name:{type:String,reflect:!0},iconContent:{type:String}};constructor(){super(),this.src="",this.name="",this.iconContent=""}updated(t){super.updated(),(t.has("src")||t.has("name"))&&this.loadIcon(),t.has("iconContent")&&this.fixSVG()}async loadIcon(){let t;this.src?t=await getIconByPath(this.src):this.name&&(t=await getIconByName(this.name)),this.iconContent=t||Icon.fallback}fixSVG(){setTimeout(()=>{const t=this.querySelector("svg");t&&(t.removeAttribute("width"),t.removeAttribute("height"),t.querySelectorAll("path, rect, circle").forEach(t=>{t.setAttribute("fill","currentColor")}))},0)}static styles=css`
1
+ import ShadowComponent from"./ShadowComponent.js";import{html,css,unsafeHTML}from"../lit-all.min.js";const cache={},getIconByPath=async t=>(cache[t]||(cache[t]=new Promise(async(e,n)=>{const o=(new AbortController).signal;try{const n=await fetch(t,{signal:o});200===n.status?e(await n.text()):404===n.status&&e(null)}catch(t){"AbortError"!==t.name&&n(t)}}).catch(()=>null)),await cache[t]),getIconByName=t=>{const e=async e=>getIconByPath(`${e}/${t}.svg`);return new Promise(async(t,n)=>{let o;for(let t=0;t<Icon.pathToIcons.length&&!o;t++)try{o=await e(Icon.pathToIcons[t])}catch(t){}t(o||null)})};export default class Icon extends ShadowComponent{static properties={src:{type:String,reflect:!0},name:{type:String,reflect:!0},iconContent:{type:String}};constructor(t=""){super(),this.src="",this.name=t,this.iconContent=""}updated(t){super.updated(),(t.has("src")||t.has("name"))&&this.loadIcon(),t.has("iconContent")&&this.fixSVG()}async loadIcon(){let t;if(this.src?t=await getIconByPath(this.src):this.name&&(t=await getIconByName(this.name)),t)this.iconContent=t;else{const t=this.innerHTML.trim();this.iconContent=t||Icon.fallback}}fixSVG(){setTimeout(()=>{const t=this.querySelector("svg");t&&(t.removeAttribute("width"),t.removeAttribute("height"),t.querySelectorAll("path, rect, circle").forEach(t=>{t.setAttribute("fill","currentColor")}))},0)}static styles=css`
2
2
  :host {
3
3
  display: inline-block;
4
4
  vertical-align: bottom;
@@ -7,4 +7,4 @@ import ShadowComponent from"./ShadowComponent.js";import{html,css,unsafeHTML}fro
7
7
  height: 1.35em;
8
8
  vertical-align: middle;
9
9
  }
10
- `;render(){return this.iconContent?html`${unsafeHTML(this.iconContent)}`:html``}static pathToIcons=["/icons"];static fallback='\n\t\t<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M480-79q-16 0-30.5-6T423-102L102-423q-11-12-17-26.5T79-480q0-16 6-31t17-26l321-321q12-12 26.5-17.5T480-881q16 0 31 5.5t26 17.5l321 321q12 11 17.5 26t5.5 31q0 16-5.5 30.5T858-423L537-102q-11 11-26 17t-31 6Zm0-80 321-321-321-321-321 321 321 321Zm-40-281h80v-240h-80v240Zm40 120q17 0 28.5-11.5T520-360q0-17-11.5-28.5T480-400q-17 0-28.5 11.5T440-360q0 17 11.5 28.5T480-320Zm0-160Z"/></svg>\n\t'}window.customElements.define("k-icon",Icon);
10
+ `;render(){return this.iconContent?html`${unsafeHTML(this.iconContent)}`:html`<slot></slot>`}static pathToIcons=["/icons"];static fallback='\n\t\t<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M480-79q-16 0-30.5-6T423-102L102-423q-11-12-17-26.5T79-480q0-16 6-31t17-26l321-321q12-12 26.5-17.5T480-881q16 0 31 5.5t26 17.5l321 321q12 11 17.5 26t5.5 31q0 16-5.5 30.5T858-423L537-102q-11 11-26 17t-31 6Zm0-80 321-321-321-321-321 321 321 321Zm-40-281h80v-240h-80v240Zm40 120q17 0 28.5-11.5T520-360q0-17-11.5-28.5T480-400q-17 0-28.5 11.5T440-360q0 17 11.5 28.5T480-320Zm0-160Z"/></svg>\n\t'}window.customElements.define("k-icon",Icon);
@@ -0,0 +1 @@
1
+ import Collapsible from"./Collapsible.js";export default class PersistantCollapsible extends Collapsible{constructor(){super(),this.storageKey=""}connectedCallback(){super.connectedCallback(),this.updateStorageKey(),this.loadFromStorage(),window.addEventListener("storage",this.handleStorageChange)}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("storage",this.handleStorageChange)}updated(e){super.updated(e),e.has("opened")&&this.saveToStorage(),e.has("id")&&(this.updateStorageKey(),this.loadFromStorage())}handleStorageChange=e=>{e.key===this.storageKey&&this.loadFromStorage()};updateStorageKey(){this.storageKey=this.id?`PersistantCollapsible-${this.id}`:""}loadFromStorage(){if(this.storageKey){const e=localStorage.getItem(this.storageKey);null!==e&&(this.opened="true"===e)}}saveToStorage(){this.storageKey&&localStorage.setItem(this.storageKey,this.opened.toString())}}customElements.define("k-p-collapsible",PersistantCollapsible);
@@ -0,0 +1,135 @@
1
+ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";import{boolExists}from"../utils/propConverters.js";import"./Icon.js";export default class PhotoViewer extends ShadowComponent{static properties={src:{type:String,reflect:!0},alt:{type:String,reflect:!0},fullscreen:{type:Boolean,reflect:!0,converter:boolExists},keyboardControls:{type:Boolean,reflect:!0,attribute:"keyboard-controls",converter:boolExists},global:{type:Boolean,reflect:!0,converter:boolExists}};constructor(){super(),this.src="",this.alt="",this.fullscreen=!1,this.keyboardControls=!0,this.global=!1}handleImageClick=()=>{this.open()};handleImageKeydown=e=>{"Enter"!==e.key||this.fullscreen||this.open()};handleCloseClick=()=>{this.close()};handleOverlayClick=e=>{e.target===e.currentTarget&&this.close()};handlePrevClick=e=>{e.stopPropagation();const t=this.getPrevSibling();t&&(this.close(),t.open())};handleNextClick=e=>{e.stopPropagation();const t=this.getNextSibling();t&&(this.close(),t.open())};handleKeydown=e=>{if("Escape"===e.key)this.close();else if("ArrowLeft"===e.key){const e=this.getPrevSibling();e&&(this.close(),e.open())}else if("ArrowRight"===e.key){const e=this.getNextSibling();e&&(this.close(),e.open())}};connectedCallback(){super.connectedCallback()}disconnectedCallback(){super.disconnectedCallback(),this.keyboardControls&&document.removeEventListener("keydown",this.handleKeydown)}updated(e){super.updated(e),e.has("fullscreen")&&(this.dispatchEvent(new CustomEvent("fullscreenchange",{detail:{fullscreen:this.fullscreen}})),this.dispatchEvent(new CustomEvent(this.fullscreen?"fullscreen":"fullscreenclose")),this.updateNavigationState(),this.keyboardControls&&(this.fullscreen?document.addEventListener("keydown",this.handleKeydown):document.removeEventListener("keydown",this.handleKeydown))),(e.has("src")||e.has("alt"))&&this.handleFullscreenCaption()}firstUpdated(){this.handleFullscreenCaption()}open(){this.fullscreen=!0}close(){this.fullscreen=!1}toggle(){this.fullscreen=!this.fullscreen}getPrevSibling(){if(this.global){const e=Array.from(document.getElementsByTagName("k-photo-viewer")),t=e.indexOf(this);return-1===t?null:e[0===t?e.length-1:t-1]}{let e=this.previousElementSibling;for(;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.previousElementSibling;if(!e&&this.hasPhotoSiblings())for(e=this.parentElement.lastElementChild;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.previousElementSibling;return e}}getNextSibling(){if(this.global){const e=Array.from(document.getElementsByTagName("k-photo-viewer")),t=e.indexOf(this);return-1===t?null:e[t===e.length-1?0:t+1]}{let e=this.nextElementSibling;for(;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.nextElementSibling;if(!e&&this.hasPhotoSiblings())for(e=this.parentElement.firstElementChild;e&&"K-PHOTO-VIEWER"!==e.tagName;)e=e.nextElementSibling;return e}}hasPhotoSiblings(){return this.global?document.getElementsByTagName("k-photo-viewer").length>1:Array.from(this.parentElement.children).filter(e=>e!==this&&"K-PHOTO-VIEWER"===e.tagName).length>0}updateNavigationState(){const e=this.fullscreen&&this.hasPhotoSiblings();this.shadowRoot.querySelectorAll(".nav-btn").forEach(t=>{t.style.display=e?"":"none"})}async handleFullscreenCaption(){await this.updateComplete;const e=this.shadowRoot.querySelector('slot[name="fullscreen-caption"]');if(e&&!e.assignedNodes().length){const e=this.shadowRoot.querySelector("slot:not([name])");(e?e.assignedNodes():[]).forEach(e=>{if(e.nodeType===Node.ELEMENT_NODE){const t=e.cloneNode(!0);t.slot="fullscreen-caption",this.appendChild(t)}})}}static styles=css`
2
+ :host {
3
+ display: block;
4
+ }
5
+ #wrapper {
6
+ position: relative;
7
+ width: 100%;
8
+ height: 100%;
9
+ }
10
+ #img {
11
+ max-width: 100%;
12
+ height: auto;
13
+ cursor: pointer;
14
+ outline: none;
15
+ border-radius: var(--img_radius, 0);
16
+ }
17
+ #img:focus {
18
+ box-shadow: var(--focus_shadow);
19
+ }
20
+ #fullscreen-overlay {
21
+ position: fixed;
22
+ top: 0;
23
+ left: 0;
24
+ right: 0;
25
+ bottom: 0;
26
+ z-index: 9999;
27
+ background: rgba(0,0,0,0.9);
28
+ padding: 2rem;
29
+ display: none;
30
+ }
31
+ :host([fullscreen]) #fullscreen-overlay {
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ }
36
+ .content {
37
+ position: relative;
38
+ max-width: 100%;
39
+ max-height: 90vh;
40
+ }
41
+ #fullscreen-img {
42
+ max-height: 75vh;
43
+ max-width: 100%;
44
+ object-fit: contain;
45
+ cursor: default;
46
+ }
47
+ #close {
48
+ position: absolute;
49
+ top: 1rem;
50
+ right: 1rem;
51
+ z-index: 1;
52
+ background: none;
53
+ border: none;
54
+ color: white;
55
+ cursor: pointer;
56
+ }
57
+ .nav-btn {
58
+ position: fixed;
59
+ top: 50%;
60
+ transform: translateY(-50%);
61
+ z-index: 1;
62
+ background: none;
63
+ border: none;
64
+ color: white;
65
+ cursor: pointer;
66
+ padding: 1rem;
67
+ opacity: 0.7;
68
+ font-size: 3rem;
69
+ -webkit-text-stroke: 1px black;
70
+ text-stroke: 1px black;
71
+ text-shadow: 0 0 3px rgba(0,0,0,0.8);
72
+ }
73
+ .nav-btn::slotted(*),
74
+ .nav-btn k-icon {
75
+ filter: drop-shadow(0 0 2px rgba(0,0,0,1)) drop-shadow(0 0 2px rgba(0,0,0,1));
76
+ }
77
+ .nav-btn:hover {
78
+ opacity: 1;
79
+ }
80
+ #prev {
81
+ left: 1rem;
82
+ }
83
+ #next {
84
+ right: 1rem;
85
+ }
86
+ .caption {
87
+ text-align: center;
88
+ max-width: 600px;
89
+ width: fit-content;
90
+ margin: 1rem auto 0;
91
+ }
92
+ #fullscreen-overlay .caption {
93
+ color: white;
94
+ }
95
+ :host([fullscreen]) .caption {
96
+ color: white;
97
+ }
98
+ `;render(){return html`
99
+ <div id="wrapper">
100
+ <img
101
+ id="img"
102
+ src="${this.src}"
103
+ alt="${this.alt}"
104
+ tabindex="0"
105
+ @click=${this.handleImageClick}
106
+ @keydown=${this.handleImageKeydown}
107
+ />
108
+ <div class="caption">
109
+ <slot></slot>
110
+ </div>
111
+ <div id="fullscreen-overlay" @click=${this.handleOverlayClick}>
112
+ <button id="close" class="no-btn" @click=${this.handleCloseClick}>
113
+ <slot name="close">
114
+ <k-icon name="close"></k-icon>
115
+ </slot>
116
+ </button>
117
+ <button id="prev" class="nav-btn no-btn" @click=${this.handlePrevClick}>
118
+ <slot name="prev">
119
+ <k-icon name="chevron-left"></k-icon>
120
+ </slot>
121
+ </button>
122
+ <button id="next" class="nav-btn no-btn" @click=${this.handleNextClick}>
123
+ <slot name="next">
124
+ <k-icon name="chevron-right"></k-icon>
125
+ </slot>
126
+ </button>
127
+ <div class="content">
128
+ <img id="fullscreen-img" src="${this.src}" alt="${this.alt}" />
129
+ <div class="caption">
130
+ <slot name="fullscreen-caption"></slot>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ </div>
135
+ `}}customElements.define("k-photo-viewer",PhotoViewer);
@@ -0,0 +1,96 @@
1
+ import{LitElement,html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import Icon from"./Icon.js";import drag from"../utils/drag.js";export default class Resize extends ShadowComponent{static properties={resizing:{type:String,reflect:!0},dimention:{type:String,reflect:!0}};constructor(){super(),this.resizing="",this.dimension="",this.startSize={width:0,height:0},this.cleanupFuncs=[]}firstUpdated(){super.firstUpdated(),this.setupDragHandlers()}disconnectedCallback(){super.disconnectedCallback(),this.cleanupFuncs.forEach(e=>e())}dragStartHandler=({element:e})=>{const{width:t,height:i}=this.getBoundingClientRect();this.startSize.width=t,this.startSize.height=i,this.resizing=e.id};dragEndHandler=()=>{this.resizing=""};dragSideHandler=({x:e})=>{this.style.width=this.startSize.width+e+"px"};dragBottomHandler=({y:e})=>{this.style.height=this.startSize.height+e+"px"};dragCornerHandler=({x:e,y:t})=>{this.style.width=this.startSize.width+e+"px",this.style.height=this.startSize.height+t+"px"};setupDragHandlers(){const e=this.shadowRoot.getElementById("side"),t=this.shadowRoot.getElementById("bottom"),i=this.shadowRoot.getElementById("corner");e&&this.cleanupFuncs.push(drag({element:e,startCallback:this.dragStartHandler,endCallback:this.dragEndHandler,callback:this.dragSideHandler,preventScroll:!0})),t&&this.cleanupFuncs.push(drag({element:t,startCallback:this.dragStartHandler,endCallback:this.dragEndHandler,callback:this.dragBottomHandler,preventScroll:!0})),i&&this.cleanupFuncs.push(drag({element:i,startCallback:this.dragStartHandler,endCallback:this.dragEndHandler,callback:this.dragCornerHandler,preventScroll:!0}))}static styles=css`
2
+ :host {
3
+ --handle_size: 1rem;
4
+
5
+ display: grid;
6
+ grid-template-columns: 1fr var(--handle_size);
7
+ grid-template-rows: 1fr var(--handle_size);
8
+ border: 1px solid var(--c_border);
9
+ border-radius: var(--radius);
10
+ min-width: 10rem;
11
+ max-width: 100%;
12
+ min-height: 10rem;
13
+ max-height: 100%;
14
+ }
15
+ :host([dimension="height"]) {
16
+ grid-template-columns: 1fr;
17
+ }
18
+ :host([dimension="width"]) {
19
+ grid-template-rows: 1fr;
20
+ }
21
+ #main {
22
+ grid-row: 1;
23
+ grid-column: 1;
24
+ overflow: auto;
25
+ }
26
+ #side {
27
+ grid-row: 1;
28
+ grid-column: 2;
29
+ cursor: ew-resize;
30
+ }
31
+ #bottom {
32
+ grid-row: 2;
33
+ grid-column: 1;
34
+ text-align: center;
35
+ cursor: ns-resize;
36
+ }
37
+ #corner {
38
+ grid-row: 2;
39
+ grid-column: 2;
40
+ overflow: hidden;
41
+ cursor: nwse-resize;
42
+ }
43
+ .handle {
44
+ display: flex;
45
+ align-items: center;
46
+ justify-content: center;
47
+ }
48
+ .handle svg {
49
+ transform: scale(0.5);
50
+ }
51
+ #bottom svg {
52
+ height: var(--handle_size);
53
+ }
54
+ #side svg {
55
+ width: var(--handle_size);
56
+ }
57
+ #corner svg {
58
+ width: var(--handle_size);
59
+ height: var(--handle_size);
60
+ }
61
+ :host(:not([resizing=""])) #main {
62
+ pointer-events: none;
63
+ }
64
+ :host([resizing="side"]) #side,
65
+ :host([resizing="corner"]) #side,
66
+ :host([resizing="corner"]) #corner,
67
+ :host([resizing="corner"]) #bottom,
68
+ :host([resizing="bottom"]) #bottom {
69
+ background-color: var(--c_highlight);
70
+ }
71
+ :host([dimension="height"]) #side,
72
+ :host([dimension="height"]) #corner,
73
+ :host([dimension="width"]) #bottom,
74
+ :host([dimension="width"]) #corner {
75
+ display: none;
76
+ }
77
+ `;render(){return html`
78
+ <div id="main">
79
+ <slot></slot>
80
+ </div>
81
+ <div id="side" class="handle">
82
+ <svg viewBox="0 0 15 64" xmlns="http://www.w3.org/2000/svg">
83
+ <path fill="currentColor" d="m 15.000001,3 c 0,-1.661998 -1.115001,-3 -2.5,-3 -1.384999,0 -2.5,1.338002 -2.5,3 v 58 c 0,1.661998 1.115001,3 2.5,3 1.384999,0 2.5,-1.338002 2.5,-3 z M 5.0000008,3 c 0,-1.661998 -1.115001,-3 -2.5,-3 C 1.1150018,0 7.5891117e-7,1.338002 7.5891117e-7,3 v 58 c 0,1.661998 1.11500104108883,3 2.50000004108883,3 1.384999,0 2.5,-1.338002 2.5,-3 z" />
84
+ </svg>
85
+ </div>
86
+ <div id="bottom" class="handle">
87
+ <svg viewBox="0 0 64 15" xmlns="http://www.w3.org/2000/svg">
88
+ <path fill="currentColor" d="M 3,0 C 1.3380017,0 0,1.1150014 0,2.5 0,3.8849986 1.3380017,5 3,5 H 61 C 62.661998,5 64,3.8849986 64,2.5 64,1.1150014 62.661998,0 61,0 Z M 3,10 C 1.3380017,10 0,11.115001 0,12.5 0,13.884999 1.3380017,15 3,15 h 58 c 1.661998,0 3,-1.115001 3,-2.5 C 64,11.115001 62.661998,10 61,10 Z" />
89
+ </svg>
90
+ </div>
91
+ <div id="corner" class="handle">
92
+ <svg version="1.1" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg">
93
+ <path fill="currentColor" d="m12.735 3.0095e-4c-0.77288 0.011702-1.6098 0.36368-2.2773 1.0313l-9.4258 9.4258c-1.1868 1.1868-1.3772 2.908-0.42773 3.8574 0.94943 0.94943 2.6687 0.7571 3.8555-0.42969l9.4258-9.4258c1.1868-1.1868 1.3772-2.906 0.42774-3.8555-0.41537-0.41537-0.977-0.61262-1.5781-0.60352zm0 8.5684c-0.77288 0.011702-1.6098 0.36564-2.2773 1.0332l-0.85744 0.85546c-1.1868 1.1868-1.3772 2.908-0.42773 3.8574 0.94943 0.94943 2.6687 0.7571 3.8555-0.42969l0.85742-0.85742c1.1868-1.1868 1.3772-2.906 0.42773-3.8555-0.41537-0.41537-0.977-0.61262-1.5781-0.60352z" />
94
+ </svg>
95
+ </div>
96
+ `}}customElements.define("k-resize",Resize);