-
Notifications
You must be signed in to change notification settings - Fork 615
Pro 6518 mobile preview #4720
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pro 6518 mobile preview #4720
Conversation
modules/@apostrophecms/ui/ui/apos/scss/global/_device_preview.scss
Outdated
Show resolved
Hide resolved
| sourceMap: true | ||
| } | ||
| } | ||
| mediaToContainerQueriesLoader, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* main: fix oversights in add missing schema fields (#4736)
|
|
||
| const containerQuery = convertToContainerQuery(mediaFeature, content); | ||
|
|
||
| return `${containerQuery} ${match}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return `${containerQuery} ${match}`; | |
| return `${containerQuery}\n\n${match}`; |
(approximative code)
to place the media query on a new line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've also put the container query after the media query
ETLaurent
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work 😮
And no iframe needed in the end!
A few comments, but the approval is very close.
| height: screen.height | ||
| } | ||
| }, | ||
| shortcut: `P,${index}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P,[n] is a bit slow if we want to quickly switch between modes.
But it's not that bad.
| export default { | ||
| name: 'TheAposContextDevicePreview', | ||
| props: { | ||
| // { screenName: { label: string, width: string, height: string, icon: string } } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wanted comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, to explain the expected props
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a good reason not to use Vue 3 here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to do like the existing vue components in the project
| }) { | ||
| document.querySelector('body').setAttribute('data-device-preview-mode', mode); | ||
| document.querySelector('[data-apos-refreshable]').setAttribute('data-resizable', this.resizable); | ||
| document.querySelector('[data-apos-refreshable]').setAttribute('data-label', this.$t(label)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we're not displaying it anymore then we can remove this line, as well as in toggleDevicePreviewMode and saveStatemethods.
| default: false | ||
| } | ||
| }, | ||
| emits: [ 'switch-device-preview-mode', 'reset-device-preview-mode' ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't find where these are being listened to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not, but if you want to listen to it and do something you can
| // Transform method used on media feature | ||
| // Can be either: | ||
| // - (mediaFeature) => { return mediaFeature; } | ||
| // - null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be enriched with another example which would illustrate why some project would need to do this. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my plan is to do it in the doc
|
|
||
| const mediaQueryRegex = /@media\s*(all|print|screen(?: and | or )?)?([^{]+)[^{]*{([\s\S]*?})\s*(\\n)*}/g; | ||
|
|
||
| const convertToContainerQuery = (mediaFeature, content) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used to be keenly against it (@ValJed would remember) but now, I think that I like having the functions definition placed after their call. I find it much more easier to read in the file (main function -> call to another function -> function definition).
I.e: you could move this function at the end, so we read the code execution in the execution order.
(this is very optional).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really have a hard time with hoisting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and the entire file is 80+ lines of code
| const root = postcss.parse(match.replaceAll(/\\[frntv]/g, '')); | ||
| root.walkRules(rule => { | ||
| const newRule = rule.clone(); | ||
| newRule.selectors = newRule.selectors.map(selector => { | ||
| if (selector.startsWith('body')) { | ||
| return selector.replace('body', 'body:not([data-device-preview-mode])'); | ||
| } | ||
|
|
||
| return `body:not([data-device-preview-mode]) ${selector}`; | ||
| }); | ||
|
|
||
| rule.replaceWith(newRule); | ||
| }); | ||
|
|
||
| return `${root.toString()}\\n\\n${containerQuery}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
beautiful 🥲
| const newRule = rule.clone(); | ||
| newRule.selectors = newRule.selectors.map(selector => { | ||
| if (selector.startsWith('body')) { | ||
| return selector.replace('body', 'body:not([data-device-preview-mode])'); | ||
| } | ||
|
|
||
| return `body:not([data-device-preview-mode]) ${selector}`; | ||
| }); | ||
|
|
||
| rule.replaceWith(newRule); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could add a comment to briefly explain why we have to disable rules in media queries when in device preview mode.
| [data-apos-refreshable]::before { | ||
| @include type-help; | ||
|
|
||
| & { | ||
| content: attr(data-label); | ||
| position: relative; | ||
| top: -1.25rem; | ||
| display: block; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we still displaying it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not visible but this is a bug
| } | ||
|
|
||
| return `body:not([data-device-preview-mode]) ${selector}`; | ||
| return `:not([data-device-preview-mode]) ${selector}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this solution (just having :not without body) but it did not work. Does it work on Chrome on your end?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed not a good idea to remove body, it's fixed
| rule.replaceWith(newRule); | ||
| }); | ||
|
|
||
| root.append(containerAtRule); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
much better indeed
| const containerAtRule = atRule.clone({ | ||
| name: 'container', | ||
| params: convertToContainerQuery(atRule.params) | ||
| .replaceAll(/(only\s*)?(all|screen|print)(,)?(\s)*(and\s*)?/g, '') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .replaceAll(/(only\s*)?(all|screen|print)(,)?(\s)*(and\s*)?/g, '') | |
| .replaceAll(/(only\s*)?(all|screen|print),?\s*(and\s*)?/g, '') |
| }; | ||
| const options = this.getOptions(schema); | ||
|
|
||
| const mediaQueryRegex = /@media[^{]*{([\s\S]*?})\s*(\\n)*}/g; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| const mediaQueryRegex = /@media[^{]*{([\s\S]*?})\s*(\\n)*}/g; | |
| const mediaQueryRegex = /@media[^{]*{[\s\S]*}\s*(\\n)*}/g; |
no need for parenthesis and question mark (* does the ?'s "job"), I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tried and the parentheses are needed, otherwise it will select extra content
changes have been made already, we have 2 approvals
* upstream/main: Release 4.8.0 (apostrophecms#4742) Enable by default, other tweaks (apostrophecms#4741) PRO-6627: Fix array reorder and labels (apostrophecms#4740) Pro 6518 mobile preview (apostrophecms#4720)
Summary
Add mobile preview feature to the admin UI

What are the specific steps to test this change?
https://preview.a3.apos.dev/
or
devicePreviewModeoption in your projectWhat kind of change does this PR introduce?
(Check at least one)
Make sure the PR fulfills these requirements:
If adding a new feature without an already open issue, it's best to open a feature request issue first and wait for approval before working on it.
Other information: