|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | | -from typing import Literal, Optional |
| 3 | +# Import the custom renderer implementations |
| 4 | +from renderers import render_capitalize, render_upper |
4 | 5 |
|
5 | 6 | from shiny import App, Inputs, ui |
6 | | -from shiny.render.renderer import Renderer, ValueFn |
7 | | - |
8 | | -####### |
9 | | -# Start of package author code |
10 | | -####### |
11 | | - |
12 | | - |
13 | | -class render_capitalize(Renderer[str]): |
14 | | - # The documentation for the class will be displayed when the user hovers over the |
15 | | - # decorator when **no** parenthesis are used. Ex: `@render_capitalize` |
16 | | - # If no documentation is supplied to the `__init__()` method, then this |
17 | | - # documentation will be displayed when parenthesis are used on the decorator. |
18 | | - """ |
19 | | - Render capitalize class documentation goes here. |
20 | | - """ |
21 | | - |
22 | | - to_case: Literal["upper", "lower", "ignore"] |
23 | | - """ |
24 | | - The case to render the value in. |
25 | | - """ |
26 | | - placeholder: bool |
27 | | - """ |
28 | | - Whether to render a placeholder value. (Defaults to `True`) |
29 | | - """ |
30 | | - |
31 | | - def auto_output_ui(self): |
32 | | - """ |
33 | | - Express UI for the renderer |
34 | | - """ |
35 | | - return ui.output_text_verbatim(self.output_name, placeholder=self.placeholder) |
36 | | - |
37 | | - def __init__( |
38 | | - self, |
39 | | - _fn: Optional[ValueFn[str]] = None, |
40 | | - *, |
41 | | - to_case: Literal["upper", "lower", "ignore"] = "upper", |
42 | | - placeholder: bool = True, |
43 | | - ) -> None: |
44 | | - # If a different set of documentation is supplied to the `__init__` method, |
45 | | - # then this documentation will be displayed when parenthesis are used on the decorator. |
46 | | - # Ex: `@render_capitalize()` |
47 | | - """ |
48 | | - Render capitalize documentation goes here. |
49 | | -
|
50 | | - It is a good idea to talk about parameters here! |
51 | | -
|
52 | | - Parameters |
53 | | - ---------- |
54 | | - to_case |
55 | | - The case to render the value. (`"upper"`) |
56 | | -
|
57 | | - Options: |
58 | | - - `"upper"`: Render the value in upper case. |
59 | | - - `"lower"`: Render the value in lower case. |
60 | | - - `"ignore"`: Do not alter the case of the value. |
61 | | -
|
62 | | - placeholder |
63 | | - Whether to render a placeholder value. (`True`) |
64 | | - """ |
65 | | - # Do not pass params |
66 | | - super().__init__(_fn) |
67 | | - self.to_case = to_case |
68 | | - |
69 | | - async def render(self) -> str | None: |
70 | | - value = await self.fn() |
71 | | - if value is None: |
72 | | - # If `None` is returned, then do not render anything. |
73 | | - return None |
74 | | - |
75 | | - ret = str(value) |
76 | | - if self.to_case == "upper": |
77 | | - return ret.upper() |
78 | | - if self.to_case == "lower": |
79 | | - return ret.lower() |
80 | | - if self.to_case == "ignore": |
81 | | - return ret |
82 | | - raise ValueError(f"Invalid value for `to_case`: {self.to_case}") |
83 | | - |
84 | | - |
85 | | -class render_upper(Renderer[str]): |
86 | | - """ |
87 | | - Minimal capitalize string transformation renderer. |
88 | | -
|
89 | | - No parameters are supplied to this renderer. This allows us to skip the `__init__()` |
90 | | - method and `__init__()` documentation. If you hover over this decorator with and |
91 | | - without parenthesis, you will see this documentation in both situations. |
92 | | -
|
93 | | - Note: This renderer is equivalent to `render_capitalize(to="upper")`. |
94 | | - """ |
95 | | - |
96 | | - def auto_output_ui(self): |
97 | | - """ |
98 | | - Express UI for the renderer |
99 | | - """ |
100 | | - return ui.output_text_verbatim(self.output_name, placeholder=True) |
101 | | - |
102 | | - async def transform(self, value: str) -> str: |
103 | | - """ |
104 | | - Transform the value to upper case. |
105 | | -
|
106 | | - This method is shorthand for the default `render()` method. It is useful to |
107 | | - transform non-`None` values. (Any `None` value returned by the app author will |
108 | | - be forwarded to the browser.) |
109 | | -
|
110 | | - Parameters |
111 | | - ---------- |
112 | | - value |
113 | | - The a non-`None` value to transform. |
114 | | -
|
115 | | - Returns |
116 | | - ------- |
117 | | - str |
118 | | - The transformed value. (Must be a subset of `Jsonifiable`.) |
119 | | - """ |
120 | | - |
121 | | - return str(value).upper() |
122 | | - |
123 | | - |
124 | | -####### |
125 | | -# End of package author code |
126 | | -####### |
127 | | - |
128 | | - |
129 | | -####### |
130 | | -# Start of app author code |
131 | | -####### |
132 | | - |
133 | | - |
134 | | -def text_row(id: str, label: str): |
135 | | - return ui.tags.tr( |
136 | | - ui.tags.td(f"{label}:"), |
137 | | - ui.tags.td(ui.output_text_verbatim(id, placeholder=True)), |
138 | | - ) |
139 | | - return ui.row( |
140 | | - ui.column(6, f"{id}:"), |
141 | | - ui.column(6, ui.output_text_verbatim(id, placeholder=True)), |
142 | | - ) |
143 | | - |
144 | 7 |
|
145 | 8 | app_ui = ui.page_fluid( |
146 | 9 | ui.h1("Capitalization renderer"), |
147 | 10 | ui.input_text("caption", "Caption:", "Data summary"), |
148 | | - ui.tags.table( |
149 | | - text_row("upper", "@render_upper"), |
150 | | - text_row("upper_with_paren", "@render_upper()"), |
151 | | - # |
152 | | - text_row("cap_upper", "@render_capitalize"), |
153 | | - text_row("cap_lower", "@render_capitalize(to='lower')"), |
154 | | - ), |
| 11 | + "@render_upper: ", |
| 12 | + ui.output_text_verbatim("upper", placeholder=True), |
| 13 | + "@render_upper(): ", |
| 14 | + ui.output_text_verbatim("upper_with_paren", placeholder=True), |
| 15 | + "@render_capitalize: ", |
| 16 | + ui.output_text_verbatim("cap_upper", placeholder=True), |
| 17 | + "@render_capitalize(to='lower'): ", |
| 18 | + ui.output_text_verbatim("cap_lower", placeholder=True), |
155 | 19 | ) |
156 | 20 |
|
157 | 21 |
|
|
0 commit comments