parent
5bfce96e64
commit
5c3d7588f9
@ -0,0 +1,120 @@
|
|||||||
|
# ---> Node
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.test
|
||||||
|
.env.production
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
|
||||||
@ -1,2 +1,94 @@
|
|||||||
# select
|
# Tiny Components - Select
|
||||||
|
Created with [Riot.js](https://riot.js.org). Select Field Element, Filter-Option to connect a [Observable](https://github.com/riot/observable). Using Styles for UI from [Plain-UI](https://plain-ui.com)
|
||||||
|
|
||||||
|
Source: [https://git.node001.net/tiny-components/select](https://git.node001.net/tiny-components/select)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Setup this registry in your project .npmrc file:
|
||||||
|
|
||||||
|
```
|
||||||
|
@tiny-components:registry=https://git.node001.net/api/packages/tiny-components/npm/
|
||||||
|
```
|
||||||
|
|
||||||
|
Install with npm or yarn
|
||||||
|
|
||||||
|
```
|
||||||
|
npm i --save @tiny-components/select
|
||||||
|
yarn add @tiny-components/select
|
||||||
|
```
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
|
||||||
|
```
|
||||||
|
<tiny-field-select></tiny-field-select>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Attribute: multiple
|
||||||
|
|
||||||
|
Select Multiple Options
|
||||||
|
|
||||||
|
### Attribute: searchable
|
||||||
|
|
||||||
|
Show Input-Field for Filtering Options, only works if Observable as Store is added and has Function Query.
|
||||||
|
|
||||||
|
### Props: options
|
||||||
|
|
||||||
|
Default Options for Start
|
||||||
|
|
||||||
|
### Props: store
|
||||||
|
|
||||||
|
import observable from '@riotjs/observable'
|
||||||
|
|
||||||
|
let store = observable({
|
||||||
|
locations: [{
|
||||||
|
'label' : 'A',
|
||||||
|
'value' : 'a'
|
||||||
|
},{
|
||||||
|
'label' : 'B',
|
||||||
|
'value' : 'b'
|
||||||
|
},{
|
||||||
|
'label' : 'C',
|
||||||
|
'value' : 'c'
|
||||||
|
},{
|
||||||
|
'label' : 'D',
|
||||||
|
'value' : 'd'
|
||||||
|
},{
|
||||||
|
'label' : 'E',
|
||||||
|
'value' : 'e'
|
||||||
|
},{
|
||||||
|
'label' : 'F',
|
||||||
|
'value' : 'f'
|
||||||
|
},{
|
||||||
|
'label' : 'G',
|
||||||
|
'value' : 'g'
|
||||||
|
},{
|
||||||
|
'label' : 'H',
|
||||||
|
'value' : 'h'
|
||||||
|
},{
|
||||||
|
'label' : 'I',
|
||||||
|
'value' : 'i'
|
||||||
|
},{
|
||||||
|
'label' : 'J',
|
||||||
|
'value' : 'j'
|
||||||
|
}],
|
||||||
|
|
||||||
|
query(value) {
|
||||||
|
if (value !== undefined) {
|
||||||
|
const results = []
|
||||||
|
|
||||||
|
// run through locations and check string contains value
|
||||||
|
for (let i = 0; i < this.locations.length; i++) {
|
||||||
|
if (this.locations[i].value.includes(value)) {
|
||||||
|
results.push(this.locations[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.trigger('update', results)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// if value is undefined, adding all locations
|
||||||
|
this.trigger('update', this.locations)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"/example/js/spritemap.js": "/example/js/spritemap.js?version=7ce719c9e00cdc31c694d971b9a5e812",
|
||||||
|
"/example/js/example.js": "/example/js/example.js?version=2451e89d416b448c318a4c3866f1ebf8",
|
||||||
|
"/example/css/styles.css": "/example/css/styles.css?version=aa01e6a7dccff39e3f40dcf35c9e9576"
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,102 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Tiny Components | Select</title>
|
||||||
|
<link rel="icon" href="data:,">
|
||||||
|
<link href="/css/styles.css" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header class="header">
|
||||||
|
<div class="bar">
|
||||||
|
<div class="bar__start">
|
||||||
|
<h1 class="m-top-4 m-bottom-4 h4">
|
||||||
|
@tiny-components/select
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div class="bar__main justify-end">
|
||||||
|
<a class="button button--small m-left-sm-3 m-bottom-0" href="https://git.node001.net/tiny-components/datepicker" rel="noopener" target="_blank">
|
||||||
|
Gitea
|
||||||
|
<svg class="m-left-3 icon fill-text" aria-hidden="true">
|
||||||
|
<use xlink:href="/symbol-defs.svg#icon-gitea"></use>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="container m-top-6">
|
||||||
|
<div class="grid">
|
||||||
|
<div class="col-12 col-md-6">
|
||||||
|
<form>
|
||||||
|
<div class="field-group">
|
||||||
|
<label class="field-label">
|
||||||
|
Locations
|
||||||
|
<tiny-field-select name="location"></tiny-field-select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-group">
|
||||||
|
<label class="field-label">
|
||||||
|
Locations (Multiple)
|
||||||
|
<tiny-field-select multiple name="location"></tiny-field-select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-group">
|
||||||
|
<label class="field-label">
|
||||||
|
Locations (Multiple + Filter)
|
||||||
|
<tiny-field-select-api multiple searchable name="location" placeholder-filter="Filter Items"></tiny-field-select-api>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script defer src="/js/example.js"></script>
|
||||||
|
<script defer>
|
||||||
|
window.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
riot.mount('tiny-field-select', {
|
||||||
|
options: [{
|
||||||
|
'label' : 'A',
|
||||||
|
'value' : 'a'
|
||||||
|
},{
|
||||||
|
'label' : 'B',
|
||||||
|
'value' : 'b'
|
||||||
|
},{
|
||||||
|
'label' : 'C',
|
||||||
|
'value' : 'c'
|
||||||
|
},{
|
||||||
|
'label' : 'D',
|
||||||
|
'value' : 'd'
|
||||||
|
},{
|
||||||
|
'label' : 'E',
|
||||||
|
'value' : 'e'
|
||||||
|
},{
|
||||||
|
'label' : 'F',
|
||||||
|
'value' : 'f'
|
||||||
|
},{
|
||||||
|
'label' : 'G',
|
||||||
|
'value' : 'g'
|
||||||
|
},{
|
||||||
|
'label' : 'H',
|
||||||
|
'value' : 'h'
|
||||||
|
},{
|
||||||
|
'label' : 'I',
|
||||||
|
'value' : 'i'
|
||||||
|
},{
|
||||||
|
'label' : 'J',
|
||||||
|
'value' : 'j'
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
riot.mount('tiny-field-select-api', {
|
||||||
|
store: LocationStore
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
|||||||
|
(self.webpackChunk_tiny_components_select=self.webpackChunk_tiny_components_select||[]).push([["spritemap"],{"?4e0c"(){eval("{\n\n//# sourceURL=webpack://@tiny-components/select/spritemap-dummy-module?\n}")}}]);
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "@tiny-components/select",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Select with filter for Desktop and Mobile",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git@git.node001.net:tiny-components/select.git"
|
||||||
|
},
|
||||||
|
"author": "Björn Hase <herrhase@node001.net>",
|
||||||
|
"license": "GPLV3",
|
||||||
|
"dependencies": {
|
||||||
|
"riot": "^10.1.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@riotjs/observable": "^4.1.1",
|
||||||
|
"@riotjs/webpack-loader": "^10.0.0",
|
||||||
|
"@tiny-components/plain-ui": "^0.6.0",
|
||||||
|
"@tiny-components/webpack": "^0.6.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack --mode development --config webpack.config.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
import * as riot from 'riot'
|
||||||
|
import Select from './select.riot'
|
||||||
|
import observable from '@riotjs/observable'
|
||||||
|
|
||||||
|
window.riot = riot
|
||||||
|
window.LocationStore = observable({
|
||||||
|
|
||||||
|
locations: [{
|
||||||
|
'label' : 'A',
|
||||||
|
'value' : 'a'
|
||||||
|
},{
|
||||||
|
'label' : 'B',
|
||||||
|
'value' : 'b'
|
||||||
|
},{
|
||||||
|
'label' : 'C',
|
||||||
|
'value' : 'c'
|
||||||
|
},{
|
||||||
|
'label' : 'D',
|
||||||
|
'value' : 'd'
|
||||||
|
},{
|
||||||
|
'label' : 'E',
|
||||||
|
'value' : 'e'
|
||||||
|
},{
|
||||||
|
'label' : 'F',
|
||||||
|
'value' : 'f'
|
||||||
|
},{
|
||||||
|
'label' : 'G',
|
||||||
|
'value' : 'g'
|
||||||
|
},{
|
||||||
|
'label' : 'H',
|
||||||
|
'value' : 'h'
|
||||||
|
},{
|
||||||
|
'label' : 'I',
|
||||||
|
'value' : 'i'
|
||||||
|
},{
|
||||||
|
'label' : 'J',
|
||||||
|
'value' : 'j'
|
||||||
|
}],
|
||||||
|
|
||||||
|
query(value) {
|
||||||
|
if (value !== undefined) {
|
||||||
|
const results = []
|
||||||
|
|
||||||
|
for (let i = 0; i < this.locations.length; i++) {
|
||||||
|
if (this.locations[i].value.includes(value)) {
|
||||||
|
results.push(this.locations[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.trigger('update', results)
|
||||||
|
} else {
|
||||||
|
this.trigger('update', this.locations)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
riot.register('tiny-field-select', Select)
|
||||||
|
riot.register('tiny-field-select-api', Select)
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
@import
|
||||||
|
'../node_modules/@tiny-components/plain-ui/src/scss/plain-ui',
|
||||||
|
'styles';
|
||||||
@ -0,0 +1,225 @@
|
|||||||
|
<tiny-field-select>
|
||||||
|
<div class="field-select">
|
||||||
|
|
||||||
|
<select name="{ props.name }" multiple style="display: none;">
|
||||||
|
<option value="{ selected[ state.keys.value ] }" selected each={ selected in state.selected }></option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<div class="field-select__options">
|
||||||
|
<div class="{ getFilterClasses(['field-select__options-filter']) }" if={ props.searchable !== undefined }>
|
||||||
|
<input type="text" class="field-text m-top-0" placeholder={ props.placeholderFilter } onkeyup={ (event) => { handleOnKeyUp(event) }} />
|
||||||
|
<button type="button" class="field-select__options-filter-reset" onclick={ (event) => { handleResetSearchable(event) } }>
|
||||||
|
⮾
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="panel">
|
||||||
|
<div class="field-select__options-panel">
|
||||||
|
<ul class="field-select__options-list">
|
||||||
|
<li class="{ getItemClasses(['field-select__options-item'], option) }" each={ option in state.options } onclick={ (event) => { handleToggle(event, option) } }>
|
||||||
|
<span class="field-select__options-item-check">
|
||||||
|
☑
|
||||||
|
</span>
|
||||||
|
<span class="field-select__options-item-uncheck">
|
||||||
|
☐
|
||||||
|
</span>
|
||||||
|
{ option[ state.keys.label ] }
|
||||||
|
</li>
|
||||||
|
<li class="field-select__item field-select__item--empty center color-danger" if={ state.options.length === 0 }>
|
||||||
|
∅
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
state: {
|
||||||
|
keys: {
|
||||||
|
label: 'label',
|
||||||
|
value: 'value'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
onBeforeMount(props, state) {
|
||||||
|
|
||||||
|
// init state
|
||||||
|
this.state = {
|
||||||
|
...state,
|
||||||
|
selected: [],
|
||||||
|
hasUpdated: false,
|
||||||
|
options: [],
|
||||||
|
query: ''
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.label) {
|
||||||
|
this.state.keys.label = props.label
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.value) {
|
||||||
|
this.state.keys.value = props.value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.options) {
|
||||||
|
this.state.options = props.options
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
onMounted() {
|
||||||
|
|
||||||
|
// if store update, add data to options
|
||||||
|
if (this.props.store) {
|
||||||
|
this.props.store.on('update', (data) => {
|
||||||
|
|
||||||
|
if (this.state.selected.length > 0) {
|
||||||
|
for (let i = 0; i < this.state.selected.length; i++) {
|
||||||
|
|
||||||
|
let found = false
|
||||||
|
|
||||||
|
for (let j = 0; j < data.length; j++) {
|
||||||
|
if (data[j][ this.state.keys.value ] == this.state.selected[i][ this.state.keys.value ]) {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found === false) {
|
||||||
|
data.unshift(this.state.selected[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.options = data
|
||||||
|
this.update()
|
||||||
|
})
|
||||||
|
|
||||||
|
this.props.store.query()
|
||||||
|
}
|
||||||
|
|
||||||
|
// getting closet form-element and add reset
|
||||||
|
this.root.closest('form').addEventListener('reset', () => {
|
||||||
|
this.reset()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
onBeforeUpdate() {
|
||||||
|
|
||||||
|
// props has changed after reset
|
||||||
|
if (this.props.selected && this.props.selected.length > 0 && !this.state.hasUpdated) {
|
||||||
|
this.state.selected = this.props.selected
|
||||||
|
this.state.hasUpdated = true
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset searchable
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
handleResetSearchable(event) {
|
||||||
|
event.target.previousElementSibling.value = ''
|
||||||
|
this.state.query = ''
|
||||||
|
this.props.store.query(this.state.query)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if pressed has ended, call query
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
handleOnKeyUp(event) {
|
||||||
|
this.state.query = event.target.value.trim()
|
||||||
|
this.props.store.query(this.state.query)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* toggle selected, if not found add to selected
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
handleToggle(event, option) {
|
||||||
|
const index = this.searchSelected(option)
|
||||||
|
|
||||||
|
if (index !== false) {
|
||||||
|
this.state.selected.splice(index, 1)
|
||||||
|
} else {
|
||||||
|
if ((this.props.multiple === undefined && this.state.selected.length > 0)) {
|
||||||
|
this.state.selected = []
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state.selected.push(option)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.update()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if item is in selected add css class
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
getItemClasses(classes, option) {
|
||||||
|
const index = this.searchSelected(option)
|
||||||
|
|
||||||
|
if (index !== false) {
|
||||||
|
classes.push('field-select__options-item--selected')
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes.join(' ')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if query is not empty show button for reset filter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
getFilterClasses(classes) {
|
||||||
|
if (this.state.query.length > 0) {
|
||||||
|
classes.push('field-select__options-filter--active')
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes.join(' ')
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search all selected for value return index or false
|
||||||
|
*
|
||||||
|
* @param options object
|
||||||
|
*/
|
||||||
|
searchSelected(option) {
|
||||||
|
let index = false
|
||||||
|
|
||||||
|
for (let i = 0; i < this.state.selected.length; i++) {
|
||||||
|
if (this.state.selected[i] && this.state.selected[i][ this.state.keys.value ] == option[ this.state.keys.value ]) {
|
||||||
|
index = i
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return index
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset component
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
reset() {
|
||||||
|
this.state.selected = []
|
||||||
|
this.state.hasUpdated = false
|
||||||
|
|
||||||
|
this.update()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</tiny-field-select>
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
.field-select {
|
||||||
|
|
||||||
|
&__options-panel {
|
||||||
|
overflow-x: scroll;
|
||||||
|
max-height: 15vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__options {
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-item-check, &-item-uncheck {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
line-height: 0;
|
||||||
|
margin: -0.2rem 0.25rem 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-item-check {
|
||||||
|
color: var(--success);
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-item-uncheck {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-item--selected {
|
||||||
|
color: white;
|
||||||
|
background-color: var(--active);
|
||||||
|
|
||||||
|
.field-select__options-item-check {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-select__options-item-uncheck {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-filter {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
.field-select__options-filter-reset {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-filter-reset {
|
||||||
|
position: absolute;
|
||||||
|
display: none;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--danger);
|
||||||
|
font-size: 1.75rem;
|
||||||
|
margin: 0.1rem 0.3rem;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__options-list {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
border: 1px solid $color__border;
|
||||||
|
border-top: 0;
|
||||||
|
border-left: 0;
|
||||||
|
border-right: 0;
|
||||||
|
padding: 0.5rem;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-top: -3px;
|
||||||
|
margin-right: 5px;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
const tinyComponentsWebpack = require('@tiny-components/webpack')
|
||||||
|
const riotRules = require('@tiny-components/webpack/rules/riot')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
module.exports = tinyComponentsWebpack({
|
||||||
|
example: [ './src/example.js' ],
|
||||||
|
styles: [ './src/example.scss' ],
|
||||||
|
}, {
|
||||||
|
publicPath: '/example/',
|
||||||
|
destination: path.resolve(process.cwd(), 'example'),
|
||||||
|
rules: [ riotRules ],
|
||||||
|
svg: {
|
||||||
|
src: [
|
||||||
|
'./src/icons/*.svg'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
purge: {
|
||||||
|
src: path.join(__dirname, './**')
|
||||||
|
}
|
||||||
|
})
|
||||||
Loading…
Reference in new issue