chore: release v0.33.1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.33.1] - 2026-04-29
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Navigation: removed the dedicated Search button from the bottom bar; the bottom bar now shows three primary module links plus the More button
|
||||||
|
- Navigation: the More sheet now opens with a full-width pill-shaped search trigger at the top, replacing the grid-cell search item
|
||||||
|
- Search: the search overlay input field is now positioned at the bottom of the screen (thumb zone) instead of the top
|
||||||
|
|
||||||
## [0.33.0] - 2026-04-29
|
## [0.33.0] - 2026-04-29
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "oikos",
|
"name": "oikos",
|
||||||
"version": "0.33.0",
|
"version": "0.33.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "oikos",
|
"name": "oikos",
|
||||||
"version": "0.33.0",
|
"version": "0.33.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bcrypt": "^6.0.0",
|
"bcrypt": "^6.0.0",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "oikos",
|
"name": "oikos",
|
||||||
"version": "0.33.0",
|
"version": "0.33.1",
|
||||||
"description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.",
|
"description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.",
|
||||||
"main": "server/index.js",
|
"main": "server/index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
+21
-56
@@ -478,20 +478,6 @@ function renderAppShell(container) {
|
|||||||
const bottomItems = document.createElement('div');
|
const bottomItems = document.createElement('div');
|
||||||
bottomItems.className = 'nav-bottom__items';
|
bottomItems.className = 'nav-bottom__items';
|
||||||
navItems().slice(0, PRIMARY_NAV).forEach((item) => bottomItems.appendChild(navItemEl(item)));
|
navItems().slice(0, PRIMARY_NAV).forEach((item) => bottomItems.appendChild(navItemEl(item)));
|
||||||
const searchNavBtn = document.createElement('button');
|
|
||||||
searchNavBtn.className = 'nav-item nav-item--search';
|
|
||||||
searchNavBtn.id = 'search-nav-btn';
|
|
||||||
searchNavBtn.setAttribute('aria-label', t('search.title'));
|
|
||||||
const searchNavIcon = document.createElement('i');
|
|
||||||
searchNavIcon.dataset.lucide = 'search';
|
|
||||||
searchNavIcon.className = 'nav-item__icon';
|
|
||||||
searchNavIcon.setAttribute('aria-hidden', 'true');
|
|
||||||
const searchNavLabel = document.createElement('span');
|
|
||||||
searchNavLabel.className = 'nav-item__label';
|
|
||||||
searchNavLabel.textContent = t('search.title');
|
|
||||||
searchNavBtn.appendChild(searchNavIcon);
|
|
||||||
searchNavBtn.appendChild(searchNavLabel);
|
|
||||||
bottomItems.appendChild(searchNavBtn);
|
|
||||||
const moreBtn = document.createElement('button');
|
const moreBtn = document.createElement('button');
|
||||||
moreBtn.className = 'nav-item nav-item--more';
|
moreBtn.className = 'nav-item nav-item--more';
|
||||||
moreBtn.id = 'more-btn';
|
moreBtn.id = 'more-btn';
|
||||||
@@ -520,19 +506,20 @@ function renderAppShell(container) {
|
|||||||
moreSheet.setAttribute('role', 'dialog');
|
moreSheet.setAttribute('role', 'dialog');
|
||||||
moreSheet.setAttribute('aria-label', t('nav.more'));
|
moreSheet.setAttribute('aria-label', t('nav.more'));
|
||||||
moreSheet.setAttribute('aria-hidden', 'true');
|
moreSheet.setAttribute('aria-hidden', 'true');
|
||||||
const searchBtn = document.createElement('button');
|
const searchTrigger = document.createElement('button');
|
||||||
searchBtn.className = 'more-item';
|
searchTrigger.className = 'more-sheet__search-trigger';
|
||||||
searchBtn.id = 'search-btn';
|
searchTrigger.id = 'search-btn';
|
||||||
const searchIcon = document.createElement('i');
|
searchTrigger.setAttribute('aria-label', t('search.title'));
|
||||||
searchIcon.dataset.lucide = 'search';
|
const searchTriggerIcon = document.createElement('i');
|
||||||
searchIcon.className = 'more-item__icon';
|
searchTriggerIcon.dataset.lucide = 'search';
|
||||||
searchIcon.setAttribute('aria-hidden', 'true');
|
searchTriggerIcon.className = 'more-sheet__search-trigger-icon';
|
||||||
const searchLabel = document.createElement('span');
|
searchTriggerIcon.setAttribute('aria-hidden', 'true');
|
||||||
searchLabel.className = 'more-item__label';
|
const searchTriggerText = document.createElement('span');
|
||||||
searchLabel.textContent = t('search.title');
|
searchTriggerText.className = 'more-sheet__search-trigger-placeholder';
|
||||||
searchBtn.appendChild(searchIcon);
|
searchTriggerText.textContent = t('search.placeholder');
|
||||||
searchBtn.appendChild(searchLabel);
|
searchTrigger.appendChild(searchTriggerIcon);
|
||||||
moreSheet.appendChild(searchBtn);
|
searchTrigger.appendChild(searchTriggerText);
|
||||||
|
moreSheet.appendChild(searchTrigger);
|
||||||
navItems().slice(PRIMARY_NAV).forEach((item) => moreSheet.appendChild(moreItemEl(item)));
|
navItems().slice(PRIMARY_NAV).forEach((item) => moreSheet.appendChild(moreItemEl(item)));
|
||||||
|
|
||||||
const searchOverlay = document.createElement('div');
|
const searchOverlay = document.createElement('div');
|
||||||
@@ -763,9 +750,8 @@ function initMoreSheet(container) {
|
|||||||
* Initialisiert die Suchfunktion (Overlay + API-Calls).
|
* Initialisiert die Suchfunktion (Overlay + API-Calls).
|
||||||
*/
|
*/
|
||||||
function initSearch(container) {
|
function initSearch(container) {
|
||||||
const searchBtn = container.querySelector('#search-btn');
|
const searchBtn = container.querySelector('#search-btn');
|
||||||
const searchNavBtn = container.querySelector('#search-nav-btn');
|
const searchClose = container.querySelector('#search-close');
|
||||||
const searchClose = container.querySelector('#search-close');
|
|
||||||
const overlay = container.querySelector('#search-overlay');
|
const overlay = container.querySelector('#search-overlay');
|
||||||
const input = container.querySelector('#search-input');
|
const input = container.querySelector('#search-input');
|
||||||
const results = container.querySelector('#search-results');
|
const results = container.querySelector('#search-results');
|
||||||
@@ -812,7 +798,6 @@ function initSearch(container) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
searchBtn.addEventListener('click', openSearch);
|
searchBtn.addEventListener('click', openSearch);
|
||||||
if (searchNavBtn) searchNavBtn.addEventListener('click', openSearch);
|
|
||||||
searchClose.addEventListener('click', closeSearch);
|
searchClose.addEventListener('click', closeSearch);
|
||||||
|
|
||||||
document.addEventListener('keydown', (e) => {
|
document.addEventListener('keydown', (e) => {
|
||||||
@@ -1137,34 +1122,14 @@ window.addEventListener('locale-changed', () => {
|
|||||||
if (bottomItems) {
|
if (bottomItems) {
|
||||||
const moreBtn = bottomItems.querySelector('#more-btn');
|
const moreBtn = bottomItems.querySelector('#more-btn');
|
||||||
const newItems = navItems().slice(0, PRIMARY_NAV).map(navItemEl);
|
const newItems = navItems().slice(0, PRIMARY_NAV).map(navItemEl);
|
||||||
// Such-Button neu erstellen (wird durch replaceChildren entfernt)
|
bottomItems.replaceChildren(...newItems, moreBtn);
|
||||||
const newSearchBtn = document.createElement('button');
|
|
||||||
newSearchBtn.className = 'nav-item nav-item--search';
|
|
||||||
newSearchBtn.id = 'search-nav-btn';
|
|
||||||
newSearchBtn.setAttribute('aria-label', t('search.title'));
|
|
||||||
const newSearchIcon = document.createElement('i');
|
|
||||||
newSearchIcon.dataset.lucide = 'search';
|
|
||||||
newSearchIcon.className = 'nav-item__icon';
|
|
||||||
newSearchIcon.setAttribute('aria-hidden', 'true');
|
|
||||||
const newSearchLbl = document.createElement('span');
|
|
||||||
newSearchLbl.className = 'nav-item__label';
|
|
||||||
newSearchLbl.textContent = t('search.title');
|
|
||||||
newSearchBtn.appendChild(newSearchIcon);
|
|
||||||
newSearchBtn.appendChild(newSearchLbl);
|
|
||||||
bottomItems.replaceChildren(...newItems, newSearchBtn, moreBtn);
|
|
||||||
// Event-Listener auf neuen Such-Button
|
|
||||||
if (newSearchBtn) {
|
|
||||||
newSearchBtn.addEventListener('click', () => {
|
|
||||||
if (window._openSearch) window._openSearch();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (moreSheet) {
|
if (moreSheet) {
|
||||||
const searchBtn = moreSheet.querySelector('#search-btn');
|
const searchTrig = moreSheet.querySelector('#search-btn');
|
||||||
const searchLbl = searchBtn?.querySelector('.more-item__label');
|
const searchTrigPlaceholder = searchTrig?.querySelector('.more-sheet__search-trigger-placeholder');
|
||||||
if (searchLbl) searchLbl.textContent = t('search.title');
|
if (searchTrigPlaceholder) searchTrigPlaceholder.textContent = t('search.placeholder');
|
||||||
const newMoreItems = navItems().slice(PRIMARY_NAV).map(moreItemEl);
|
const newMoreItems = navItems().slice(PRIMARY_NAV).map(moreItemEl);
|
||||||
moreSheet.replaceChildren(searchBtn, ...newMoreItems);
|
moreSheet.replaceChildren(searchTrig, ...newMoreItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelectorAll('[data-route]').forEach((el) => {
|
document.querySelectorAll('[data-route]').forEach((el) => {
|
||||||
|
|||||||
@@ -268,6 +268,43 @@
|
|||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── More-Sheet Suchtrigger ── */
|
||||||
|
.more-sheet__search-trigger {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--space-2);
|
||||||
|
padding: 0 var(--space-4);
|
||||||
|
height: var(--target-lg);
|
||||||
|
border-radius: var(--radius-full);
|
||||||
|
border: 1.5px solid var(--color-border);
|
||||||
|
background-color: var(--color-surface-elevated);
|
||||||
|
color: var(--color-text-tertiary);
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
transition: background-color var(--transition-fast), border-color var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.more-sheet__search-trigger:active {
|
||||||
|
background-color: var(--color-surface-hover);
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
transform: scale(0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
.more-sheet__search-trigger-icon {
|
||||||
|
width: var(--space-4);
|
||||||
|
height: var(--space-4);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.more-sheet__search-trigger-placeholder {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Such-Overlay ── */
|
/* ── Such-Overlay ── */
|
||||||
.search-overlay {
|
.search-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@@ -275,7 +312,7 @@
|
|||||||
background-color: var(--color-surface);
|
background-color: var(--color-surface);
|
||||||
z-index: calc(var(--z-nav) + 3);
|
z-index: calc(var(--z-nav) + 3);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column-reverse;
|
||||||
transform: translateY(100%);
|
transform: translateY(100%);
|
||||||
transition: transform 0.25s var(--ease-out);
|
transition: transform 0.25s var(--ease-out);
|
||||||
}
|
}
|
||||||
@@ -288,8 +325,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--space-3);
|
gap: var(--space-3);
|
||||||
padding: calc(var(--space-4) + var(--safe-area-inset-top)) var(--space-4) var(--space-3);
|
padding: var(--space-3) var(--space-4) calc(var(--space-4) + var(--safe-area-inset-bottom));
|
||||||
border-bottom: 1px solid var(--color-border-subtle);
|
border-top: 1px solid var(--color-border-subtle);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-overlay__input {
|
.search-overlay__input {
|
||||||
@@ -331,7 +368,8 @@
|
|||||||
.search-overlay__results {
|
.search-overlay__results {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: var(--space-4);
|
padding: var(--space-4) var(--space-4) var(--space-2);
|
||||||
|
padding-top: calc(var(--space-4) + var(--safe-area-inset-top));
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-overlay__empty {
|
.search-overlay__empty {
|
||||||
|
|||||||
Reference in New Issue
Block a user