% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/paintr-app.R
\name{ptr_ui}
\alias{ptr_ui}
\title{Self-contained UI for a \code{ggpaintr} Formula}
\usage{
ptr_ui(
  formula,
  id = NULL,
  envir = parent.frame(),
  ui_text = NULL,
  expr_check = TRUE,
  css = NULL,
  shared = NULL
)
}
\arguments{
\item{formula}{Either a single character scalar containing a ggplot
expression with \code{ggpaintr} placeholders, or an unquoted ggplot
expression supplied directly (the primary form). Captured with
\code{\link[rlang:defusing-advanced]{rlang::enexpr()}} exactly as \code{\link[=ptr_app]{ptr_app()}} / \code{\link[=ptr_server]{ptr_server()}}, so a
formula stored in a variable via \code{\link[rlang:expr]{rlang::expr()}} can be passed by its
bare symbol (\verb{f <- rlang::expr(ggplot(...)); ptr_ui(f, "id")}) or
spliced with \verb{!!} (\code{ptr_ui(!!f, "id")}); a subscripted/extracted
element resolves bare too (\code{ptr_ui(plots[[1]], "id")}, \code{holder$body}).
See \code{\link[=ptr_app]{ptr_app()}} for the full contract (symbol resolution, wrapper
unwrap, native-pipe caveat).}

\item{id}{Optional module id; the namespace prefix for inputs and outputs.
Defaults to \code{NULL} (identity namespace, single-instance use).}

\item{envir}{Environment used to resolve a \code{formula} passed as a bare
symbol and any local data objects. Defaults to the calling frame.}

\item{ui_text}{Optional named list of copy overrides; see \code{\link[=ptr_ui_text]{ptr_ui_text()}}
for the full schema and current defaults.}

\item{expr_check}{Controls formula-level \code{ppExpr} validation: \code{TRUE}
(default) applies the built-in denylist + AST walker; \code{FALSE} disables
formula-level validation; a \code{list} with \code{deny_list}/\code{allow_list} entries
customises the formula-level policy. Runtime-typed \code{ppExpr} input is
always screened against the built-in denylist regardless. See the
safety chapter of the ggpaintr book (development-version docs):
\url{https://willju-wangqian.github.io/ggpaintr-book/safety.html}.}

\item{css}{Optional character vector of paths to additional CSS files;
linked after \code{ggpaintr}'s bundled stylesheet so its rules win. See
\code{\link[=ptr_app]{ptr_app()}} for the full semantics. Defaults to \code{NULL}.}

\item{shared}{Optional coordinator object from \code{\link[=ptr_shared]{ptr_shared()}} for the
multi-instance embedding. Forwarded verbatim to \code{\link[=ptr_ui_controls]{ptr_ui_controls()}}.
When \code{NULL} (the single-instance default) the inline "Shared controls"
section renders \strong{every} \code{shared = "..."} placeholder in \code{formula}.
When a \code{ptr_shared_spec} is supplied, its cross-formula keys
(\code{shared$panel_keys}) are excluded here because they belong to the one
standalone \code{\link[=ptr_shared_panel]{ptr_shared_panel()}}; only this formula's formula-local
shared keys render inline. Defaults to \code{NULL}.}
}
\value{
A \code{shiny.tag} — a \code{fluidPage} shell containing the controls panel,
plot output, and asset bundle.
}
\description{
The L2 default-layout UI bundle for a \code{ggpaintr} formula: owns its own
\code{.ptr-app} theme scope + asset bundle (nothing else to remember) and is
namespaced by \code{id}. Pair with the single public \code{\link[=ptr_server]{ptr_server()}}. For a
hand-composed L3 layout, use the bare \verb{ptr_ui_*} pieces instead and pair
them with the same \code{\link[=ptr_server]{ptr_server()}}.
}
\examples{
# Expression form (primary): an unquoted ggplot call.
ui <- ptr_ui(ggplot(mtcars, aes(x = ppVar, y = ppVar)) + geom_point(), "plot1")
# Stored in a variable, spliced with `!!` (paired with ptr_server(!!f, "plot1")).
f <- rlang::expr(ggplot(mtcars, aes(x = ppVar, y = ppVar)) + geom_point())
ui2 <- ptr_ui(!!f, "plot1")
# String form (fallback): equivalent.
ui3 <- ptr_ui("ggplot(mtcars, aes(x = ppVar, y = ppVar)) + geom_point()", "plot1")
}
\seealso{
\code{\link[=ptr_server]{ptr_server()}}, \code{\link[=ptr_css]{ptr_css()}} for the \verb{css =} argument and
themable CSS custom properties.
}
