diff --git a/ui/src/services/files/components/tailwind/FileTable.scala b/ui/src/services/files/components/tailwind/FileTable.scala index 48a5868..29567ca 100644 --- a/ui/src/services/files/components/tailwind/FileTable.scala +++ b/ui/src/services/files/components/tailwind/FileTable.scala @@ -8,7 +8,7 @@ import java.time.format.FormatStyle import java.time.ZoneId import java.util.Locale -import ui.components.tailwind.TimeUtils +import works.iterative.ui.components.tailwind.TimeUtils def FileTable( files: Signal[List[File]], diff --git a/ui/src/services/files/components/tailwind/FileTable.scala b/ui/src/services/files/components/tailwind/FileTable.scala index 48a5868..29567ca 100644 --- a/ui/src/services/files/components/tailwind/FileTable.scala +++ b/ui/src/services/files/components/tailwind/FileTable.scala @@ -8,7 +8,7 @@ import java.time.format.FormatStyle import java.time.ZoneId import java.util.Locale -import ui.components.tailwind.TimeUtils +import works.iterative.ui.components.tailwind.TimeUtils def FileTable( files: Signal[List[File]], diff --git a/ui/src/ui/components/tailwind/Component.scala b/ui/src/ui/components/tailwind/Component.scala index c22e6e4..9f32359 100644 --- a/ui/src/ui/components/tailwind/Component.scala +++ b/ui/src/ui/components/tailwind/Component.scala @@ -1,5 +1,6 @@ package works.iterative.ui.components.tailwind +import com.raquo.laminar.api.L.HtmlElement import com.raquo.laminar.nodes.ReactiveHtmlElement import org.scalajs.dom @@ -11,3 +12,6 @@ : Conversion[Component[Ref], ReactiveHtmlElement[Ref]] with def apply(component: Component[Ref]): ReactiveHtmlElement[Ref] = component.element + +trait HtmlComponent[C]: + extension (c: C) def element: HtmlElement diff --git a/ui/src/services/files/components/tailwind/FileTable.scala b/ui/src/services/files/components/tailwind/FileTable.scala index 48a5868..29567ca 100644 --- a/ui/src/services/files/components/tailwind/FileTable.scala +++ b/ui/src/services/files/components/tailwind/FileTable.scala @@ -8,7 +8,7 @@ import java.time.format.FormatStyle import java.time.ZoneId import java.util.Locale -import ui.components.tailwind.TimeUtils +import works.iterative.ui.components.tailwind.TimeUtils def FileTable( files: Signal[List[File]], diff --git a/ui/src/ui/components/tailwind/Component.scala b/ui/src/ui/components/tailwind/Component.scala index c22e6e4..9f32359 100644 --- a/ui/src/ui/components/tailwind/Component.scala +++ b/ui/src/ui/components/tailwind/Component.scala @@ -1,5 +1,6 @@ package works.iterative.ui.components.tailwind +import com.raquo.laminar.api.L.HtmlElement import com.raquo.laminar.nodes.ReactiveHtmlElement import org.scalajs.dom @@ -11,3 +12,6 @@ : Conversion[Component[Ref], ReactiveHtmlElement[Ref]] with def apply(component: Component[Ref]): ReactiveHtmlElement[Ref] = component.element + +trait HtmlComponent[C]: + extension (c: C) def element: HtmlElement diff --git a/ui/src/ui/components/tailwind/TimeUtils.scala b/ui/src/ui/components/tailwind/TimeUtils.scala index da0cc94..3bb2d6e 100644 --- a/ui/src/ui/components/tailwind/TimeUtils.scala +++ b/ui/src/ui/components/tailwind/TimeUtils.scala @@ -1,4 +1,4 @@ -package ui.components.tailwind +package works.iterative.ui.components.tailwind import com.raquo.laminar.api.L.{*, given} diff --git a/ui/src/services/files/components/tailwind/FileTable.scala b/ui/src/services/files/components/tailwind/FileTable.scala index 48a5868..29567ca 100644 --- a/ui/src/services/files/components/tailwind/FileTable.scala +++ b/ui/src/services/files/components/tailwind/FileTable.scala @@ -8,7 +8,7 @@ import java.time.format.FormatStyle import java.time.ZoneId import java.util.Locale -import ui.components.tailwind.TimeUtils +import works.iterative.ui.components.tailwind.TimeUtils def FileTable( files: Signal[List[File]], diff --git a/ui/src/ui/components/tailwind/Component.scala b/ui/src/ui/components/tailwind/Component.scala index c22e6e4..9f32359 100644 --- a/ui/src/ui/components/tailwind/Component.scala +++ b/ui/src/ui/components/tailwind/Component.scala @@ -1,5 +1,6 @@ package works.iterative.ui.components.tailwind +import com.raquo.laminar.api.L.HtmlElement import com.raquo.laminar.nodes.ReactiveHtmlElement import org.scalajs.dom @@ -11,3 +12,6 @@ : Conversion[Component[Ref], ReactiveHtmlElement[Ref]] with def apply(component: Component[Ref]): ReactiveHtmlElement[Ref] = component.element + +trait HtmlComponent[C]: + extension (c: C) def element: HtmlElement diff --git a/ui/src/ui/components/tailwind/TimeUtils.scala b/ui/src/ui/components/tailwind/TimeUtils.scala index da0cc94..3bb2d6e 100644 --- a/ui/src/ui/components/tailwind/TimeUtils.scala +++ b/ui/src/ui/components/tailwind/TimeUtils.scala @@ -1,4 +1,4 @@ -package ui.components.tailwind +package works.iterative.ui.components.tailwind import com.raquo.laminar.api.L.{*, given} diff --git a/ui/src/ui/components/tailwind/data_display/description_lists/LeftAlignedInCard.scala b/ui/src/ui/components/tailwind/data_display/description_lists/LeftAlignedInCard.scala new file mode 100644 index 0000000..f1eafd0 --- /dev/null +++ b/ui/src/ui/components/tailwind/data_display/description_lists/LeftAlignedInCard.scala @@ -0,0 +1,70 @@ +package works.iterative.ui.components.tailwind.data_display.description_lists + +import com.raquo.laminar.api.L.{*, given} +import works.iterative.ui.components.tailwind.HtmlComponent +import works.iterative.ui.UIString +import works.iterative.ui.components.tailwind.TimeUtils +import java.time.LocalDate + +case class OptionalLabeledValue( + label: UIString, + v: Option[Modifier[HtmlElement]] +) + +object OptionalLabeledValue: + def makeValue[V](label: UIString, v: V)(using + r: OptionalValueRender[V] + ): OptionalLabeledValue = OptionalLabeledValue(label, r.render(v)) + +trait OptionalValueRender[V]: + def render(v: V): Option[Modifier[HtmlElement]] + +object OptionalValueRender: + given stringValue: OptionalValueRender[String] with + def render(v: String): Option[Modifier[HtmlElement]] = Some( + v: Modifier[HtmlElement] + ) + given dateValue: OptionalValueRender[LocalDate] with + def render(v: LocalDate): Option[Modifier[HtmlElement]] = Some( + TimeUtils.formatDate(v) + ) + given optionValue[T](using + r: OptionalValueRender[T] + ): OptionalValueRender[Option[T]] with + def render(v: Option[T]): Option[Modifier[HtmlElement]] = + v.flatMap(r.render) + +case class LeftAlignedInCard( + title: String, + subtitle: String, + data: List[OptionalLabeledValue] +) + +object LeftAlignedInCard: + given leftAlignedInCardComponent: HtmlComponent[LeftAlignedInCard] with + extension (d: LeftAlignedInCard) + def element: HtmlElement = + div( + cls := "bg-white shadow overflow-hidden sm:rounded-lg", + div( + cls := "px-4 py-5 sm:px-6", + h3(cls := "text-lg leading-6 font-medium text-gray-900", d.title), + p(cls := "mt-1 max-w-2xl text-sm text-gray-500", d.subtitle) + ), + div( + cls := "border-t border-gray-200 px-4 py-5 sm:p-0", + dl( + cls := "sm:divide-y sm:divide-gray-200", + d.data.collect { case OptionalLabeledValue(label, Some(body)) => + div( + cls := "py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6", + dt(cls := "text-sm font-medium text-gray-500", label), + dd( + cls := "mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2", + body + ) + ) + } + ) + ) + )