Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 148 additions & 6 deletions css/playground.css
Original file line number Diff line number Diff line change
Expand Up @@ -1932,7 +1932,7 @@
content: ' ·';
}

/* --- the Nextcloud 34 app menu --- */
/* --- the Nextcloud 34 and 35 app menu --- */

#nldesign-preview .nldesign-pg-appmenu {
display: inline-flex;
Expand Down Expand Up @@ -1975,7 +1975,7 @@
.button-vue__icon svg` takes `mask: var(--header-menu-icon-mask)`, which is
a top-to-bottom alpha ramp — solid to 25%, 55% transparent by 90%. Without
it the specimen's glyphs are flat where the real ones lift off the bar. */
#nldesign-preview .nldesign-pg-header.is-v34 .nldesign-pg-glyphbox svg {
#nldesign-preview .nldesign-pg-header.is-modern .nldesign-pg-glyphbox svg {
mask: var(--header-menu-icon-mask, none);
}

Expand Down Expand Up @@ -2017,12 +2017,15 @@
mask: url('../img/app.svg') center / 20px no-repeat;
}

/* --- the 34 header: search in the middle --- */
/* --- the 34-and-newer header: search in the middle --- */

/* The foreground chain the real bar uses: Nextcloud's own plain-text token,
with Thematiq's header token in front of it because that is what
element-overrides.css puts on the live header. */
#nldesign-preview .nldesign-pg-header.is-v34 {
element-overrides.css puts on the live header. `is-modern` rather than a
per-version class: this chain, and the glyph fade above, are what 34
introduced and 35 kept, so naming them after either version would say the
other one does something else. */
#nldesign-preview .nldesign-pg-header.is-modern {
position: relative;
color: var(
--nldesign-color-header-text,
Expand Down Expand Up @@ -2095,13 +2098,152 @@
background-color: rgb(0 0 0 / 22%);
}

#nldesign-preview .nldesign-pg-search .unified-search-input__label {
#nldesign-preview .nldesign-pg-search .unified-search-input__label,
#nldesign-preview .nldesign-pg-searchresting .unified-search-input__label {
min-width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}

/* --- the 35 header: three columns, and a real field --- */

/* 35 replaced 34's floating search with a genuine `.header-center` between a
`.header-start` and a `.header-end` that both GROW. That is the mechanism
keeping the field dead centre: two equal side columns, not an absolutely
positioned track. Drawing it any other way would put the field in the middle
of the leftover space, which moves with the length of the app name. */
#nldesign-preview .nldesign-pg-header.is-v35 .nldesign-pg-header-start {
display: flex;
flex: 1 0;
align-items: center;
gap: 2px;
min-width: 0;
}

/* The auto margin that centred nothing on 34 has to go: with both sides
growing there is no free space left for it to absorb, and leaving it in
would read as the thing doing the work. */
#nldesign-preview .nldesign-pg-header.is-v35 .nldesign-pg-header-end {
flex: 1 0;
justify-content: flex-end;
margin-left: 0;
}

/* One shared highlight spanning the waffle AND the current app, where 34 gave
each button its own. Nothing hovers in a specimen, so only the geometry is
drawn — but the element has to exist, because a theme still reaching
`.app-menu__waffle:hover` paints a pill the width of the waffle alone. */
#nldesign-preview .nldesign-pg-appmenutrigger {
position: relative;
display: inline-flex;
align-items: center;
border-radius: var(--border-radius-element, 8px);
}

/* The level 35 added around the app icon. Core puts the header's alpha ramp on
this outer element and the icon shape on the inner one, so the fade applies
once to the glyph rather than to a box behind it. */
#nldesign-preview .nldesign-pg-appfade {
display: inline-flex;
flex: none;
align-items: center;
mask: var(--header-menu-icon-mask, none);
}

/* Core says `clamp(200px, 35vw, 700px)` — 700, where 34 capped at 600. The
percentage stands in for the vw for the same reason it does on 34: the
header IS the viewport in life, and here it is a ~980px drawing of one. */
#nldesign-preview .nldesign-pg-search35 {
display: flex;
flex: 0 1 auto;
align-items: center;
width: clamp(140px, 35%, 700px);
min-width: 0;
}

/* The field itself. Same black wash and inset shadow 34's button carried — 35
changed what the element IS, not what it looks like at rest — on the full
clickable area rather than 8px inside it. */
#nldesign-preview .nldesign-pg-searchfield {
position: relative;
display: flex;
align-items: center;
width: 100%;
height: var(--default-clickable-area, 34px);
border-radius: var(--border-radius-element, 8px);
background-color: rgb(0 0 0 / 15%);
box-shadow: inset 0 2px 0 rgb(0 0 0 / 12%);
color: inherit;
font-size: 13px;
}

/* On dark themes the plain black wash all but disappears into the bar, so 35
tints it with the primary element colour instead. That swap is a token
decision, which makes it something an admin is here to judge. */
[data-theme-dark] #nldesign-preview .nldesign-pg-searchfield,
[data-theme-dark-highcontrast] #nldesign-preview .nldesign-pg-searchfield {
background-color: color-mix(
in srgb,
var(--color-primary-element) 16%,
transparent
);
}

/* The magnifier and placeholder. Core absolutely positions this group and
slides it from the centre to the leading edge on focus, using container
units to find the centre. A specimen is drawn at rest and never focuses, so
only the resting position is transcribed — as a centred flex row, which
lands in the same place without the machinery that moves it. */
#nldesign-preview .nldesign-pg-searchresting {
display: flex;
flex: 1;
align-items: center;
justify-content: center;
gap: 8px;
min-width: 0;
padding-inline: 12px;
color: color-mix(
in srgb,
var(--color-background-plain-text) 70%,
var(--color-background-plain)
);
pointer-events: none;
}

/* The Ctrl-K hint, pinned to the trailing edge and overlaid on the field. */
#nldesign-preview .nldesign-pg-searchkbd {
position: absolute;
inset-inline-end: 4px;
top: 50%;
display: flex;
gap: 2px;
transform: translateY(-50%);
pointer-events: none;
}

#nldesign-preview .nldesign-pg-searchkbd kbd {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 12px;
height: 12px;
padding-inline: 5px;
border: 1px solid
color-mix(in srgb, var(--color-background-plain-text) 20%, transparent);
border-bottom-width: 2px;
border-radius: var(--border-radius-small, 4px);
background: none;
color: color-mix(
in srgb,
var(--color-background-plain-text) 70%,
var(--color-background-plain)
);
font-family: inherit;
font-size: 13px;
line-height: 1;
}

/* The token editor's own heading, lifted up here with the tab strip.
* It governs the specimens AND the rows below them — left in the editor it
* sat between the two and read as a heading for the rows alone, with the
Expand Down
122 changes: 111 additions & 11 deletions js/playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,13 @@
* anyway, because "my 33 will look like this" is the question an admin
* actually asks, and answering it with a version they did not name leaves
* them wondering whether it was understood.
*
* 34 and 35 do NOT draw the same header, which is why 35 is its own entry
* rather than a second label on the 34 one: 35 gave the bar a real centre
* column, turned the search trigger into a field, and grouped the waffle
* and the current app under one highlight.
*/
var HEADER_VERSIONS = [32, 33, 34]
var HEADER_VERSIONS = [32, 33, 34, 35]

/**
* Whether a state is one the admin makes rather than one the stage draws.
Expand Down Expand Up @@ -1574,9 +1579,11 @@
*
* This exists so an admin can answer "what does my theme do to the header
* after the upgrade" without upgrading — 34 replaced the app-entry row with
* a waffle and a current-app button, and a theme that reached the old shape
* may reach nothing in the new one. The version they are running is marked,
* so switching away from it is visibly a hypothetical.
* a waffle and a current-app button, and 35 grouped those two under one
* highlight and turned the search trigger into a field in a centre column.
* A theme that reached the old shape may reach nothing in the new one. The
* version they are running is marked, so switching away from it is visibly
* a hypothetical.
*
* @param {Object} state The instrument state.
* @param {Object} component The header component.
Expand Down Expand Up @@ -2015,20 +2022,35 @@
var STAGES = {
'header-bar': function (state, component, version) {
var major = headerMajor(version)
// Everything from 34 on: the waffle app menu, the centred search,
// and the glyph fade. `columns` is the narrower 35-only change.
var modern = major >= 34
// 35 rebuilt the bar as three real columns — `.header-start`,
// `.header-center`, `.header-end` — where 34 centred the search by
// floating it over a two-column bar. The start side has to become a
// wrapper for that, because a centre column only stays centred
// between a start and an end that both grow.
var columns = major >= 35

var start =
'<span class="nldesign-pg-header-logo logo"></span>'
+ (modern ? (columns ? appMenu35() : appMenu34()) : appMenu32())

return (
'<div class="nldesign-pg-header'
+ (modern ? ' is-v34' : '')
+ (modern ? ' is-modern' : '')
+ (columns ? ' is-v35' : '')
+ '">'
+ '<span class="nldesign-pg-header-logo logo"></span>'
+ (modern ? appMenu34() : appMenu32())
+ (columns
? '<span class="nldesign-pg-header-start">' + start + '</span>'
: start)
// Version drift, not a style choice, and the second of two in
// this one bar: 34 moved the search into the middle, where 32
// and 33 put a magnifier among the glyphs on the right. It is
// branched the way the app menu above it is, because the shape
// and the position both changed, not just the class name.
+ (modern ? headerSearch34() : '')
// and 33 put a magnifier among the glyphs on the right, and 35
// turned that middle trigger into a field. It is branched the
// way the app menu above it is, because the shape and the
// position both changed, not just the class name.
+ (modern ? (columns ? headerSearch35() : headerSearch34()) : '')
+ '<span class="nldesign-pg-header-end">'
+ (modern ? '' : headerSearch32())
+ glyph('bell', 'nldesign-pg-bell', 'bellDot')
Expand Down Expand Up @@ -2965,6 +2987,42 @@
)
}

/**
* The app menu as Nextcloud 35 draws it: the same two buttons, grouped.
*
* 35 kept 34's waffle and current-app buttons and wrapped them in one
* `.app-menu__trigger`, which carries a single highlight spanning both —
* where 34 gave each button its own. The pair is what an admin sees change,
* so the wrapper is drawn even though nothing hovers here: a theme reaching
* `.app-menu__waffle:hover` for the highlight paints nothing on 35, and
* that is only visible if the element it moved to exists in the specimen.
*
* The current-app icon also gained a level: 34 rendered an `<img
* class="app-menu__current-app-icon">`, 35 nests a `__glyph` span inside
* that class so the outer element can carry the header fade while the inner
* one carries the icon shape.
*
* @return {string} The markup.
*/
function appMenu35() {
return (
'<nav class="app-menu nldesign-pg-appmenu">'
+ '<span class="app-menu__trigger nldesign-pg-appmenutrigger">'
+ '<span class="app-menu__waffle nldesign-pg-waffle">'
+ glyph('waffle')
+ '</span>'
+ '<span class="app-menu__current-app nldesign-pg-currentapp">'
+ '<span class="app-menu__current-app-icon nldesign-pg-appfade">'
+ '<span class="app-menu__current-app-glyph nldesign-pg-appicon">'
+ '</span>'
+ '</span>'
+ '<span class="app-menu__current-app-name">Thematiq</span>'
+ '</span>'
+ '</span>'
+ '</nav>'
)
}

/**
* The header search, as 32 and 33 draw it: a glyph among the account ones.
*
Expand Down Expand Up @@ -3015,6 +3073,48 @@
)
}

/**
* The header search, as 35 draws it: a real field in a real centre column.
*
* 34's trigger was a `<button class="unified-search-input__button">` that
* carried the icon and the label itself. 35 replaced it with
* `.unified-search-input__field` — a container holding a decorative
* `__resting` group (magnifier and placeholder), the real `<input>`, and a
* `__shortcut` hint naming the keys that focus it. The placeholder changed
* with it, from "Search apps, files, tags, messages …" to "Apps, files,
* messages, and more".
*
* The `<input>` is not drawn. It is transparent and empty until the field
* is focused, and the specimen is a still life of the bar at rest — the
* same reason 34's popover is left out of the app menu above. What the
* resting field does show is the surface an admin is judging: a black wash
* on the header, which a dark token set turns invisible unless core's own
* primary tint reaches it.
*
* @return {string} The markup.
*/
function headerSearch35() {
return (
'<search class="unified-search-input nldesign-pg-search35">'
+ '<span class="unified-search-input__field nldesign-pg-searchfield">'
+ '<span class="unified-search-input__resting nldesign-pg-searchresting">'
+ glyph('magnify', 'unified-search-input__icon')
+ '<span class="unified-search-input__label">'
+ t('thematiq', 'Apps, files, messages, and more')
+ '</span>'
+ '</span>'
// Real `<kbd>` elements, because that is what NcKbd renders and
// what core's own rule for the hint selects — `:deep(kbd)`, not a
// class of its own.
+ '<span class="unified-search-input__shortcut nldesign-pg-searchkbd"'
+ ' aria-hidden="true">'
+ '<kbd>Ctrl</kbd><kbd>K</kbd>'
+ '</span>'
+ '</span>'
+ '</search>'
)
}

/** Material icon paths, for the actions menu rows. */
var EYE_PATH =
'M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,'
Expand Down
3 changes: 2 additions & 1 deletion l10n/be.js
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,8 @@ OC.L10N.register(
"%n entry": "%n entry",
"Nothing": "Nothing",
"Changed": "Changed",
"+%n more": "+%n more"
"+%n more": "+%n more",
"Apps, files, messages, and more": "Apps, files, messages, and more"
},
"nplurals=2; plural=(n != 1);"
)
3 changes: 2 additions & 1 deletion l10n/be.json
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,8 @@
"%n entry": "%n entry",
"Nothing": "Nothing",
"Changed": "Changed",
"+%n more": "+%n more"
"+%n more": "+%n more",
"Apps, files, messages, and more": "Apps, files, messages, and more"
},
"plurals": {}
}
3 changes: 2 additions & 1 deletion l10n/bg.js
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,8 @@ OC.L10N.register(
"%n entry": "%n entry",
"Nothing": "Nothing",
"Changed": "Changed",
"+%n more": "+%n more"
"+%n more": "+%n more",
"Apps, files, messages, and more": "Apps, files, messages, and more"
},
"nplurals=2; plural=(n != 1);"
)
3 changes: 2 additions & 1 deletion l10n/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,8 @@
"%n entry": "%n entry",
"Nothing": "Nothing",
"Changed": "Changed",
"+%n more": "+%n more"
"+%n more": "+%n more",
"Apps, files, messages, and more": "Apps, files, messages, and more"
},
"plurals": {}
}
Loading
Loading