diff --git a/src/wuttaweb/forms/widgets.py b/src/wuttaweb/forms/widgets.py
index 13331b3..72c4d79 100644
--- a/src/wuttaweb/forms/widgets.py
+++ b/src/wuttaweb/forms/widgets.py
@@ -147,6 +147,24 @@ class NotesWidget(TextAreaWidget):
readonly_template = "readonly/notes"
+class CopyableTextWidget(Widget): # pylint: disable=abstract-method
+ """
+ A readonly text widget which adds a "copy" icon/link just after
+ the text.
+ """
+
+ def serialize(self, field, cstruct, **kw): # pylint: disable=empty-docstring
+ """ """
+ if not cstruct:
+ return colander.null
+
+ return HTML.tag("wutta-copyable-text", **{"text": cstruct})
+
+ def deserialize(self, field, pstruct): # pylint: disable=empty-docstring
+ """ """
+ raise NotImplementedError
+
+
class WuttaCheckboxChoiceWidget(CheckboxChoiceWidget):
"""
Custom widget for :class:`python:set` fields.
diff --git a/src/wuttaweb/templates/wutta-components.mako b/src/wuttaweb/templates/wutta-components.mako
index 45c08d3..093121d 100644
--- a/src/wuttaweb/templates/wutta-components.mako
+++ b/src/wuttaweb/templates/wutta-components.mako
@@ -4,6 +4,7 @@
${self.make_wutta_autocomplete_component()}
${self.make_wutta_button_component()}
${self.make_wutta_checked_password_component()}
+ ${self.make_wutta_copyable_text_component()}
${self.make_wutta_datepicker_component()}
${self.make_wutta_timepicker_component()}
${self.make_wutta_filter_component()}
@@ -349,6 +350,72 @@
%def>
+<%def name="make_wutta_copyable_text_component()">
+
+
+%def>
+
<%def name="make_wutta_datepicker_component()">