A Code outputs
A.1 Mastering {htmltools}
A.1.1 Shiny RPG rework
Final code expected in section 2.6.6:
rpgSelect <- function(inputId, label, choices, selected = NULL,
multiple = FALSE, size = NULL) {
selectTag <- shiny::selectInput(
inputId,
label,
choices,
selected,
multiple,
selectize = FALSE,
width = NULL,
size
)
selectClass <- if (is.null(size)) { # add class
"rpgui-dropdown"
} else {
"rpgui-list"
}
tagQuery(selectTag)$
removeAttrs("class")$ # remove outer div class
find(".control-label")$
removeAttrs("class")$ # remove class from child label
siblings()$ # go down to the div
children()$ # go down to the select tag
addClass(selectClass)$ # add class to child select
resetSelected()$# go back to div parent
each(function(x, i) {
x$children[[2]] <- x$children[[2]]$children
})$ # replace div parent
allTags()
}A.2 Case Study 2: Mobile development with Shiny
A.2.1 Reconstruct {shinyMobile}
The init.js code obtained in 23 is shown below.
$( document ).ready(function() {
// collect all data elements stored in body
let config = $(document).find('script[data-for="app"]');
config = JSON.parse(config.html());
// always erase existing root value just in case
// the user changes the root. This may be harmful
config.root = '#app';
// store app methods
config.methods = {
toggleDarkTheme: function() {
var self = this;
var $html = self.$('html');
$html.toggleClass('theme-dark');
}
};
// create app instance
app = new Framework7(config);
// init main view
let mainView = app.views.create('.view-main');
// tapHold custom css
if (config.hasOwnProperty('touch')) {
if (config.touch.tapHold) {
$('<style>')
.prop('type', 'text/css')
.html(
`-moz-user-select: none;
-webkit-user-select: none;
user-select: none;`
)
.appendTo('head');
}
}
let notification = app.notification.create({
text: 'Hello, how are you?',
on: {
opened: function () {
console.log('Notification opened');
}
}
}).open();
let otherMessage = app.notification.create({
text: 'You look great!'
});
// equivalent to setTimeout ...
app.utils.nextTick(function() {
otherMessage.open();
}, 1000);
// taphold test
$('#mybutton').on('taphold', function () {
app.dialog.alert('Tap hold fired!');
});
// Set color theme
if (config.hasOwnProperty('color')) {
let color = config.color
let colorCSS = app.utils.colorThemeCSSProperties(color);
$('<style>')
.prop('type', 'text/css')
.html(`:root {
--f7-theme-color:${colorCSS['--f7-theme-color']};
--f7-theme-color-rgb:${colorCSS['--f7-theme-color-rgb']};
--f7-theme-color-shade:${colorCSS['--f7-theme-color-shade']};
--f7-theme-color-tint:${colorCSS['--f7-theme-color-tint']};
}`)
.appendTo('head');
}
// Filled theme
if (!config.hasOwnProperty('filled')) config.filled = false;
if (config.filled) {
let filledCSS = `
:root,
:root.theme-dark,
:root .theme-dark {
--f7-bars-bg-color: var(--f7-theme-color);
--f7-bars-bg-color-rgb: var(--f7-theme-color-rgb);
--f7-bars-translucent-opacity: 0.9;
--f7-bars-text-color: #fff;
--f7-bars-link-color: #fff;
--f7-navbar-subtitle-text-color: rgba(255,255,255,0.85);
--f7-bars-border-color: transparent;
--f7-tabbar-link-active-color: #fff;
--f7-tabbar-link-inactive-color: rgba(255,255,255,0.54);
--f7-sheet-border-color: transparent;
--f7-tabbar-link-active-border-color: #fff;
}
.appbar,
.navbar,
.toolbar,
.subnavbar,
.calendar-header,
.calendar-footer {
--f7-touch-ripple-color: var(--f7-touch-ripple-white);
--f7-link-highlight-color: var(--f7-link-highlight-white);
--f7-button-text-color: #fff;
--f7-button-pressed-bg-color: rgba(255,255,255,0.1);
}
.navbar-large-transparent,
.navbar-large.navbar-transparent {
--f7-navbar-large-title-text-color: #000;
--r: 0;
--g: 122;
--b: 255;
--progress: var(--f7-navbar-large-collapse-progress);
--f7-bars-link-color: rgb(
calc(var(--r) + (255 - var(--r)) * var(--progress)),
calc(var(--g) + (255 - var(--g)) * var(--progress)),
calc(var(--b) + (255 - var(--b)) * var(--progress))
);
}
.theme-dark .navbar-large-transparent,
.theme-dark .navbar-large.navbar-transparent {
--f7-navbar-large-title-text-color: #fff;
}`;
$('<style>')
.prop('type', 'text/css')
.html(`${filledCSS}`)
.appendTo('head');
}
// dark mode
if (!config.hasOwnProperty('dark')) config.dark = false;
if (config.dark) {
app.methods.toggleDarkTheme();
}
});
A.3 R + Shiny + React: welcome {reactR}
A.3.1 Introduction to {reactR}
A.3.1.1 Exercise 2
JSX code from section 27.2.7 may be found below.
import { reactShinyInput } from 'reactR';
// reactstrap components
import { Button } from 'reactstrap';
function ActionButton({configuration, value, setValue}) {
let iconTag, btnCl, innerTag;
if (...) {
btnCl = 'btn-icon';
innerTag = <>
<span className="btn-inner--icon">
<i className=... />
</span>
<span className="btn-inner--text">...</span>
</>;
} else {
innerTag = configuration.label;
}
let outlined;
if (...) {
outlined = true;
}
return (
<Button
color={configuration.status}
className=...
outline=...
size=...
onClick={() => setValue(value + 1)}>
{innerTag}
</Button>
);
}
reactShinyInput(
'.action_button',
'reactstrapTest.action_button',
ActionButton
);