Added new components

This commit is contained in:
sairaj mote 2021-07-12 02:05:01 +05:30
parent e858394b03
commit e4c1f9a642
7 changed files with 313 additions and 5 deletions

View File

@ -11,8 +11,8 @@ smNotifications.innerHTML = `
display: -webkit-box;
display: -ms-flexbox;
display: flex;
--icon-height: 2rem;
--icon-width: 2rem;
--icon-height: 1.5rem;
--icon-width: 1.5rem;
}
.hide{
opacity: 0 !important;
@ -147,7 +147,7 @@ customElements.define('sm-notifications', class extends HTMLElement {
this.animationOptions = {
duration: 300,
fill: "forwards",
easing: "ease"
easing: "cubic-bezier(0.175, 0.885, 0.32, 1.275)"
}
this.push = this.push.bind(this)
@ -200,7 +200,7 @@ customElements.define('sm-notifications', class extends HTMLElement {
opacity: '1'
},
{
transform: `translateY(1rem)`,
transform: `translateY(0.5rem)`,
opacity: '0'
}
], this.animationOptions).onfinish = () => {

File diff suppressed because one or more lines are too long

48
components/dist/sm-spinner.js vendored Normal file
View File

@ -0,0 +1,48 @@
const spinner = document.createElement('template')
spinner.innerHTML = `
<style>
*{
padding: 0;
margin: 0;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.loader {
height: 1.6rem;
width: 1.6rem;
stroke-width: 8;
overflow: visible;
stroke: var(--accent-color);
fill: none;
stroke-dashoffset: 180;
stroke-dasharray: 180;
animation: load 2s infinite, spin 1s linear infinite;
}
@keyframes load {
50% {
stroke-dashoffset: 0;
}
100%{
stroke-dashoffset: -180;
}
}
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
</style>
<svg viewBox="0 0 64 64" class="loader"><circle cx="32" cy="32" r="32" /></svg>
`
class SquareLoader extends HTMLElement {
constructor() {
super();
this.attachShadow({
mode: 'open'
}).append(spinner.content.cloneNode(true))
}
}
window.customElements.define('sm-spinner', SquareLoader);

1
components/dist/sm-spinner.min.js vendored Normal file
View File

@ -0,0 +1 @@
const spinner=document.createElement("template");spinner.innerHTML='\n<style> \n*{\n padding: 0;\n margin: 0;\n -webkit-box-sizing: border-box;\n box-sizing: border-box;\n}\n.loader {\n height: 1.6rem;\n width: 1.6rem;\n stroke-width: 8;\n overflow: visible;\n stroke: var(--accent-color);\n fill: none;\n stroke-dashoffset: 180;\n stroke-dasharray: 180;\n animation: load 2s infinite, spin 1s linear infinite;\n}\n@keyframes load {\n 50% {\n stroke-dashoffset: 0;\n }\n 100%{\n stroke-dashoffset: -180;\n }\n}\n\n@keyframes spin {\n 100% {\n transform: rotate(360deg);\n }\n}\n</style>\n<svg viewBox="0 0 64 64" class="loader"><circle cx="32" cy="32" r="32" /></svg>\n\n';class SquareLoader extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}).append(spinner.content.cloneNode(!0))}}window.customElements.define("sm-spinner",SquareLoader);

233
components/dist/text-field.js vendored Normal file
View File

@ -0,0 +1,233 @@
const textField = document.createElement('template')
textField.innerHTML = `
<style>
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
.text-field{
display: flex;
align-items: center;
}
.text{
padding: 0.6rem 0;
transition: background-color 0.3s;
border-bottom: 0.15rem solid transparent;
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
word-break: break-word;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
.text:focus{
outline: none;
border-bottom: 0.15rem solid var(--accent-color);
}
.text:focus-visible{
outline: none;
background: solid rgba(var(--text-color), 0.06);
}
.editable{
border-bottom: 0.15rem solid rgba(var(--text-color), 0.6);
}
.icon-container{
position: relative;
margin-left: 0.5rem;
height: 1.8rem;
width: 1.8rem;
}
.icon{
position: absolute;
cursor: pointer;
fill: none;
stroke-width: 8;
stroke: rgba(var(--text-color), 1);
height: 1.8rem;
width: 1.8rem;
padding: 0.4rem;
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
}
.hide{
display: none;
}
</style>
<div class="text-field">
<div class="text" part="text"></div>
<div class="icon-container">
<svg class="edit-button icon" viewBox="0 0 64 64">
<title>Edit</title>
<path d="M46.73,14.81l7,7,7.65-7.6A7.15,7.15,0,0,0,61.39,4L60.11,2.77a7.23,7.23,0,0,0-10.19,0L3.87,48.57a5,5,0,0,0-1.39,2.6L.53,61.27a1.74,1.74,0,0,0,2,2l10.15-1.94A5.06,5.06,0,0,0,15.34,60L49.6,25.9"/>
</svg>
<svg class="save-button icon hide" viewBox="0 0 64 64">
<title>Save</title>
<polyline points="0.35 31.82 21.45 52.98 63.65 10.66"/>
</svg>
</div>
</div>
`
customElements.define('text-field', class extends HTMLElement{
constructor(){
super()
this.attachShadow({
mode: 'open'
}).append(textField.content.cloneNode(true))
this.textField = this.shadowRoot.querySelector('.text-field')
this.textContainer = this.textField.children[0]
this.iconsContainer = this.textField.children[1]
this.editButton = this.textField.querySelector('.edit-button')
this.saveButton = this.textField.querySelector('.save-button')
this.isTextEditable = false
this.isDisabled = false
this.fireEvent = this.fireEvent.bind(this)
this.setEditable = this.setEditable.bind(this)
this.setNonEditable = this.setNonEditable.bind(this)
this.revert = this.revert.bind(this)
}
static get observedAttributes(){
return ['disable']
}
get value(){
return this.text
}
set value(val) {
this.text = val
this.textContainer.textContent = val
this.setAttribute('value', val)
}
set disabled(val) {
this.isDisabled = val
if(this.isDisabled)
this.setAttribute('disable', '')
else
this.removeAttribute('disable')
}
fireEvent(value){
let event = new CustomEvent('contentchanged', {
bubbles: true,
cancelable: true,
composed: true,
detail: {
value
}
});
this.dispatchEvent(event);
}
setEditable(){
if(this.isTextEditable) return
this.textContainer.contentEditable = true
this.textContainer.classList.add('editable')
this.textContainer.focus()
document.execCommand('selectAll', false, null);
this.editButton.animate(this.rotateOut, this.animOptions).onfinish = () => {
this.editButton.classList.add('hide')
}
setTimeout(() => {
this.saveButton.classList.remove('hide')
this.saveButton.animate(this.rotateIn, this.animOptions)
}, 100);
this.isTextEditable = true
}
setNonEditable(){
if (!this.isTextEditable) return
this.textContainer.contentEditable = false
this.textContainer.classList.remove('editable')
if (this.text !== this.textContainer.textContent.trim()) {
this.setAttribute('value', this.textContainer.textContent)
this.text = this.textContainer.textContent.trim()
this.fireEvent(this.text)
}
this.saveButton.animate(this.rotateOut, this.animOptions).onfinish = () => {
this.saveButton.classList.add('hide')
}
setTimeout(() => {
this.editButton.classList.remove('hide')
this.editButton.animate(this.rotateIn, this.animOptions)
}, 100);
this.isTextEditable = false
}
revert(){
if (this.textContainer.isContentEditable) {
this.value = this.text
this.setNonEditable()
}
}
connectedCallback(){
this.text
if (this.hasAttribute('value')) {
this.text = this.getAttribute('value')
this.textContainer.textContent = this.text
}
if(this.hasAttribute('disable'))
this.isDisabled = true
else
this.isDisabled = false
this.rotateOut = [
{
transform: 'rotate(0)',
opacity: 1
},
{
transform: 'rotate(90deg)',
opacity: 0
},
]
this.rotateIn = [
{
transform: 'rotate(-90deg)',
opacity: 0
},
{
transform: 'rotate(0)',
opacity: 1
},
]
this.animOptions = {
duration: 300,
easing: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
fill: 'forwards'
}
if (!this.isDisabled) {
this.iconsContainer.classList.remove('hide')
this.textContainer.addEventListener('dblclick', this.setEditable)
this.editButton.addEventListener('click', this.setEditable)
this.saveButton.addEventListener('click', this.setNonEditable)
}
}
attributeChangedCallback(name) {
if (name === 'disable') {
if (this.hasAttribute('disable')) {
this.iconsContainer.classList.add('hide')
this.textContainer.removeEventListener('dblclick', this.setEditable)
this.editButton.removeEventListener('click', this.setEditable)
this.saveButton.removeEventListener('click', this.setNonEditable)
this.revert()
}
else {
this.iconsContainer.classList.remove('hide')
this.textContainer.addEventListener('dblclick', this.setEditable)
this.editButton.addEventListener('click', this.setEditable)
this.saveButton.addEventListener('click', this.setNonEditable)
}
}
}
disconnectedCallback() {
this.textContainer.removeEventListener('dblclick', this.setEditable)
this.editButton.removeEventListener('click', this.setEditable)
this.saveButton.removeEventListener('click', this.setNonEditable)
}
})

1
components/dist/text-field.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -309,6 +309,14 @@
<sm-option value="3">option3</sm-option>
</sm-select>
</section>
<section id="spinner_page" class="page hide-completely">
<h1 class="page__title">Spinner</h1>
<p>
<code>&lt;sm-select&gt;</code> is very similar to starndatd HTML5 select and it's markup stucture is
also identical.
</p>
<sm-spinner></sm-spinner>
</section>
<section id="strip_select_page" class="page hide-completely">
<h1 class="page__title">Strip select</h1>
@ -375,6 +383,13 @@
</p>
<sm-textarea placeholder="Add some text here..." rows="4"></sm-textarea>
</section>
<section id="text_field_page" class="page hide-completely">
<h1 class="page__title">Text field</h1>
<p class="description">
To start using SM Components
</p>
<text-field value="Double click me!"></text-field>
</section>
</div>
</main>
<template id="nav_item_template">
@ -399,11 +414,13 @@
<script src="dist/popup.js"></script>
<script src="dist/radio.js"></script>
<script src="dist/select.js"></script>
<script src="dist/sm-spinner.js"></script>
<script src="dist/strip-select.js"></script>
<script src="dist/switch.js"></script>
<script src="dist/tabs.js"></script>
<script src="dist/tags-input.js"></script>
<script src="dist/textarea.js"></script>
<script src="dist/text-field.js"></script>
<script id="default_ui_library">
const domRefs = {};
@ -817,6 +834,10 @@
name: 'Select',
pageId: 'select_page'
},
{
name: 'Spinner',
pageId: 'spinner_page'
},
{
name: 'Strip select',
pageId: 'strip_select_page'
@ -833,6 +854,10 @@
name: 'textarea',
pageId: 'textarea_page'
},
{
name: 'Text field',
pageId: 'text_field_page'
},
]
function sideNav(show = true) {
if (show) {