diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js index 9c6ef77f..63636de9 100644 --- a/docs/.vitepress/config.js +++ b/docs/.vitepress/config.js @@ -1,5 +1,6 @@ import { resolve } from 'path' import svgLoader from 'vite-svg-loader' +import eslintPlugin from 'vite-plugin-eslint' export default { title: 'Omorphia', @@ -66,6 +67,7 @@ export default { ], }, }), + eslintPlugin(), ], resolve: { alias: { diff --git a/docs/components/dropdown-select.md b/docs/components/dropdown-select.md index 80107d62..6248873d 100644 --- a/docs/components/dropdown-select.md +++ b/docs/components/dropdown-select.md @@ -7,18 +7,29 @@ const value = ref(null) + + ```vue ``` diff --git a/lib/assets/styles/classes.scss b/lib/assets/styles/classes.scss index 0578cd2e..6e1a6651 100644 --- a/lib/assets/styles/classes.scss +++ b/lib/assets/styles/classes.scss @@ -315,6 +315,11 @@ a, margin: auto; } } + + &.transparent { + background: none; + box-shadow: none; + } } .btn-group { @@ -469,17 +474,33 @@ a, // TABLE .table { - .table-container { - display: grid; - grid-template-rows: repeat(auto-fill, auto); - width: 100%; - border-radius: var(--radius-md); - overflow: hidden; - } + display: grid; + grid-template-rows: repeat(auto-fill, auto); + width: 100%; + border-radius: var(--radius-md); + overflow: hidden; .table-row { display: grid; - grid-template-columns: 1fr 4fr 1.5fr; + + transition: opacity 0.5s ease-in-out, filter 0.2s ease-in-out, scale 0.05s ease-in-out, + outline 0.2s ease-in-out; + + &.selectable:focus-visible, + &.selectable:hover { + cursor: pointer; + filter: brightness(0.85); + } + + &.selectable:active { + filter: brightness(0.8); + scale: 0.99; + } + } + + .entire-row { + grid-template-columns: 1fr !important; + align-items: center; } .table-head { @@ -491,42 +512,25 @@ a, .table-cell { padding: 1rem; height: 100%; - align-items: center; vertical-align: center; display: flex; } + .name-cell { + padding-left: 0; + } + .table-text { overflow: hidden; white-space: nowrap; - text-overflow: ellipsis; - display: flex; - - span { - display: inline-block; - text-overflow: ellipsis; - overflow: hidden; - } + text-overflow: fade; } - button { - width: 100%; - display: flex; - align-items: center; - justify-content: center; - - span { - display: inherit; - align-items: center; - justify-content: center; - } + .table-row:nth-child(even) .table-cell { + background-color: var(--color-bg); } } -.table-row:nth-child(even) .table-cell { - background-color: var(--color-bg); -} - // CUSTOM COMPONENTS // TODO: MOST OF THESE SHOULD BE MOVED TO AN OMORPHIA COMPONENT .textarea-wrapper { diff --git a/lib/assets/styles/defaults.scss b/lib/assets/styles/defaults.scss index 071b2aaf..128da0a6 100644 --- a/lib/assets/styles/defaults.scss +++ b/lib/assets/styles/defaults.scss @@ -56,7 +56,6 @@ input[type='number'], textarea { border-radius: var(--radius-md); box-sizing: border-box; - border: 2px solid transparent; // safari iOS rounds inputs by default // set the appearance to none to prevent this appearance: none !important; @@ -64,10 +63,9 @@ textarea { color: var(--color-base); padding: 0.5rem 1rem; font-weight: var(--font-weight-medium); - outline: 2px solid transparent; - box-shadow: var(--shadow-inset-sm), 0 0 0 0 transparent; transition: box-shadow 0.1s ease-in-out; min-height: 40px; + box-shadow: var(--shadow-inset-sm), 0 0 0 0 transparent; &:focus, &:focus-visible { @@ -87,7 +85,7 @@ textarea { } &::placeholder { - color: var(--color-contrast); + color: var(--color-base); opacity: 0.6; } } @@ -111,16 +109,19 @@ input[type='number'] { } &:focus-within svg { - color: var(--color-base); opacity: 1; + color: var(--color-contrast); } - :not(input) { + svg { position: absolute; left: 0.75rem; height: 1.25rem; width: 1.25rem; z-index: 1; + + color: var(--color-base); + opacity: 0.6; } } diff --git a/lib/assets/styles/variables.scss b/lib/assets/styles/variables.scss index 11b20df6..14a327d9 100644 --- a/lib/assets/styles/variables.scss +++ b/lib/assets/styles/variables.scss @@ -21,6 +21,7 @@ html { .light { --color-bg: #e5e7eb; --color-raised-bg: #ffffff; + --color-super-raised-bg: #e9e9e9; --color-button-bg: hsl(220, 13%, 91%); --color-base: hsl(221, 39%, 11%); @@ -59,6 +60,7 @@ html { .dark { --color-bg: #16181c; --color-raised-bg: #26292f; + --color-super-raised-bg: #40434a; --color-button-bg: hsl(222, 13%, 30%); --color-base: var(--dark-color-base); diff --git a/lib/components/base/DropdownSelect.vue b/lib/components/base/DropdownSelect.vue index a1a4bd4c..d2f7f075 100644 --- a/lib/components/base/DropdownSelect.vue +++ b/lib/components/base/DropdownSelect.vue @@ -12,35 +12,50 @@ @keydown.up.prevent="focusPreviousOption" @keydown.down.prevent="focusNextOptionOrOpen" > -
+
{{ selectedOption }}
- -
+
+
- - +
+ + +
-
- + +
@@ -67,6 +82,14 @@ export default { type: String, default: null, }, + renderUp: { + type: Boolean, + default: false, + }, + disabled: { + type: Boolean, + default: false, + }, }, emits: ['input', 'change', 'update:modelValue'], data() { @@ -92,8 +115,10 @@ export default { }, methods: { toggleDropdown() { - this.dropdownVisible = !this.dropdownVisible - this.$refs.dropdown.focus() + if (!this.disabled) { + this.dropdownVisible = !this.dropdownVisible + this.$refs.dropdown.focus() + } }, selectOption(option, index) { this.radioValue = option @@ -101,8 +126,10 @@ export default { this.dropdownVisible = false }, onFocus() { - this.focusedOptionIndex = this.options.findIndex((option) => option === this.selectedValue) - this.dropdownVisible = true + if (!this.disabled) { + this.focusedOptionIndex = this.options.findIndex((option) => option === this.selectedValue) + this.dropdownVisible = true + } }, onBlur(event) { if (!this.isChildOfDropdown(event.relatedTarget)) { @@ -110,19 +137,23 @@ export default { } }, focusPreviousOption() { - if (!this.dropdownVisible) { - this.toggleDropdown() + if (!this.disabled) { + if (!this.dropdownVisible) { + this.toggleDropdown() + } + this.focusedOptionIndex = + (this.focusedOptionIndex + this.options.length - 1) % this.options.length + this.$refs.optionElements[this.focusedOptionIndex].focus() } - this.focusedOptionIndex = - (this.focusedOptionIndex + this.options.length - 1) % this.options.length - this.$refs.optionElements[this.focusedOptionIndex].focus() }, focusNextOptionOrOpen() { - if (!this.dropdownVisible) { - this.toggleDropdown() + if (!this.disabled) { + if (!this.dropdownVisible) { + this.toggleDropdown() + } + this.focusedOptionIndex = (this.focusedOptionIndex + 1) % this.options.length + this.$refs.optionElements[this.focusedOptionIndex].focus() } - this.focusedOptionIndex = (this.focusedOptionIndex + 1) % this.options.length - this.$refs.optionElements[this.focusedOptionIndex].focus() }, isChildOfDropdown(element) { let currentNode = element @@ -157,13 +188,18 @@ export default { cursor: pointer; user-select: none; border-radius: var(--radius-md); + box-shadow: var(--shadow-inset-sm), 0 0 0 0 transparent; - &:hover { - filter: brightness(1.25); - transition: filter 0.3s ease-in-out; + &.disabled { + cursor: not-allowed; + filter: brightness(0.75); } - &.dropdown-open { + &.render-up { + border-radius: 0 0 var(--radius-md) var(--radius-md); + } + + &.render-down { border-radius: var(--radius-md) var(--radius-md) 0 0; } @@ -181,7 +217,7 @@ export default { border-left: 0.4rem solid transparent; border-right: 0.4rem solid transparent; border-top: 0.4rem solid var(--color-base); - transition: transform 0.3s ease; + transition: transform 0.2s ease; &.rotate { transform: rotate(180deg); } @@ -189,11 +225,10 @@ export default { } .options { - position: absolute; - width: 100%; z-index: 10; - border-radius: 0 0 var(--radius-lg) var(--radius-lg); - overflow: hidden; + max-height: min(12rem); + overflow-y: auto; + box-shadow: var(--shadow-inset-sm), 0 0 0 0 transparent; .option { background-color: var(--color-button-bg); @@ -204,19 +239,20 @@ export default { user-select: none; &:hover { - filter: brightness(1.25); - transition: filter 0.3s ease-in-out; + filter: brightness(0.85); + transition: filter 0.2s ease-in-out; } &:focus { outline: 0; - filter: brightness(1.25); - transition: filter 0.3s ease-in-out; + filter: brightness(0.85); + transition: filter 0.2s ease-in-out; } &.selected-option { background-color: var(--color-brand); color: var(--color-accent-contrast); + font-weight: bolder; } input { @@ -226,24 +262,43 @@ export default { } } -.slide-fade-enter { - opacity: 0; - transform: translateY(-20px); +.options-enter-active, +.options-leave-active { + transition: transform 0.2s ease; } -.slide-fade-enter-to { - opacity: 1; - transform: translateY(0); +.options-enter-from, +.options-leave-to { + &.up { + transform: translateY(100%); + } + + &.down { + transform: translateY(-100%); + } } -.slide-fade-enter-active, -.slide-fade-leave-active { - transition: opacity 0.5s ease, transform 0.3s ease; +.options-enter-to, +.options-leave-from { + &.up { + transform: translateY(0%); + } } -.slide-fade-leave, -.slide-fade-leave-to { - opacity: 0; - transform: translateY(-20px); +.options-wrapper { + position: absolute; + width: 100%; + overflow: auto; + z-index: 9; + + &.up { + top: 0; + transform: translateY(-100%); + border-radius: var(--radius-md) var(--radius-md) 0 0; + } + + &.down { + border-radius: 0 0 var(--radius-md) var(--radius-md); + } } diff --git a/package.json b/package.json index a1782c9c..c0be99ae 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "omorphia", "type": "module", - "version": "0.4.7", + "version": "0.4.11", "files": [ "dist" ], @@ -18,7 +18,7 @@ "build": "vite build", "lint:js": "eslint --ext .js,.vue,.ts,.jsx,.tsx,.html,.vue .", "lint": "npm run lint:js && prettier --check .", - "fix": "eslint --fix --ext .js,.vue,.ts,.jsx,.tsx,.html,.vue .", + "fix": "eslint --fix --ext .js,.vue,.ts,.jsx,.tsx,.html,.vue . && prettier --write .", "docs:dev": "vitepress dev docs", "docs:build": "vitepress build docs", "docs:preview": "vitepress preview docs"