diff --git a/docs/docs/changelog.md b/docs/docs/changelog.md index b995b98..d117c1d 100644 --- a/docs/docs/changelog.md +++ b/docs/docs/changelog.md @@ -8,6 +8,7 @@ - Fixed `clock` widget blanking after widget updates -> https://github.com/Panonim/dynacat/pull/160 - Calendar now shows releases on the previous and next month days visible in the grid -> https://github.com/Panonim/dynacat/issues/156 - Calendar now properly shows upcoming shows -> https://github.com/Panonim/dynacat/issues/156 +- Added a `grid` style to the `bookmarks` widget -> https://github.com/Panonim/dynacat/issues/162 # Changes for 3.0.0 - Moved the compose template to [Panonim/dynacat-compose-template](https://github.com/Panonim/dynacat-compose-template), the install command is now a single `curl | tar` with no `sed` renaming diff --git a/docs/docs/configuration.md b/docs/docs/configuration.md index 8187ef2..cfa299e 100644 --- a/docs/docs/configuration.md +++ b/docs/docs/configuration.md @@ -793,6 +793,10 @@ Preview: | Name | Type | Required | | ---- | ---- | -------- | | groups | array | yes | +| style | string | no | + +##### `style` +Set to `grid` to show the links as a grid of icon tiles with the title and description underneath, which works best when each link has an `icon`. Leave it empty for the default list. ##### `groups` An array of groups which can optionally have a title and a custom color. diff --git a/internal/dynacat/static/css/widget-bookmarks.css b/internal/dynacat/static/css/widget-bookmarks.css index 19c5ad2..e8f33e6 100644 --- a/internal/dynacat/static/css/widget-bookmarks.css +++ b/internal/dynacat/static/css/widget-bookmarks.css @@ -33,3 +33,43 @@ height: 20px; opacity: 0.8; } + +.bookmarks-grid { + display: grid; + gap: 2rem 0.5rem; + grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); +} + +.bookmarks-grid-icon-container { + width: max-content; + margin-inline: auto; + padding: 1rem; + border-radius: var(--border-radius); + background-color: var(--color-widget-background-highlight); + transition: background-color 0.2s, transform 0.2s; +} + +.bookmarks-grid-icon { + display: block; + width: 4rem; + height: 4rem; + object-fit: contain; + opacity: 0.8; + transition: opacity 0.2s; +} + +.bookmarks-grid-link:hover .bookmarks-grid-icon-container, +.bookmarks-grid-link:focus-visible .bookmarks-grid-icon-container { + background-color: color-mix(in srgb, var(--bookmarks-group-color) 18%, var(--color-widget-background-highlight)); + transform: translateY(-2px); +} + +.bookmarks-grid-link:hover .bookmarks-grid-icon, +.bookmarks-grid-link:focus-visible .bookmarks-grid-icon { + opacity: 1; +} + +.bookmarks-grid-link:hover .bookmarks-grid-title, +.bookmarks-grid-link:focus-visible .bookmarks-grid-title { + color: var(--bookmarks-group-color); +} diff --git a/internal/dynacat/templates/bookmarks-grid.html b/internal/dynacat/templates/bookmarks-grid.html new file mode 100644 index 0000000..766e9cc --- /dev/null +++ b/internal/dynacat/templates/bookmarks-grid.html @@ -0,0 +1,32 @@ +{{ template "widget-base.html" . }} + +{{ define "widget-content-classes" }}{{ if .Frameless }}widget-content-frameless{{ end }}{{ end }} + +{{ define "widget-content" }} +
+ {{- range .Groups }} +
+ {{- if ne .Title "" }} +
{{ .Title }}
+ {{- end }} + +
+ {{- end }} +
+{{ end }} diff --git a/internal/dynacat/widget-bookmarks.go b/internal/dynacat/widget-bookmarks.go index f7920eb..0832ec9 100644 --- a/internal/dynacat/widget-bookmarks.go +++ b/internal/dynacat/widget-bookmarks.go @@ -5,11 +5,13 @@ import ( ) var bookmarksWidgetTemplate = mustParseTemplate("bookmarks.html", "widget-base.html") +var bookmarksGridWidgetTemplate = mustParseTemplate("bookmarks-grid.html", "widget-base.html") type bookmarksWidget struct { widgetBase `yaml:",inline"` cachedHTML template.HTML `yaml:"-"` Frameless bool `yaml:"frameless"` + Style string `yaml:"style"` Groups []struct { Title string `yaml:"title"` Color *hslColorField `yaml:"color"` @@ -65,17 +67,25 @@ func (widget *bookmarksWidget) initialize() error { func (widget *bookmarksWidget) setProviders(providers *widgetProviders) { widget.widgetBase.setProviders(providers) widget.cacheIcons() - widget.cachedHTML = widget.renderTemplate(widget, bookmarksWidgetTemplate) + widget.cachedHTML = widget.render() } func (widget *bookmarksWidget) Render() template.HTML { if widget.cachedHTML == "" { - widget.cachedHTML = widget.renderTemplate(widget, bookmarksWidgetTemplate) + widget.cachedHTML = widget.render() } return widget.cachedHTML } +func (widget *bookmarksWidget) render() template.HTML { + if widget.Style == "grid" { + return widget.renderTemplate(widget, bookmarksGridWidgetTemplate) + } + + return widget.renderTemplate(widget, bookmarksWidgetTemplate) +} + func (widget *bookmarksWidget) cacheIcons() { if widget.Providers == nil { return diff --git a/internal/dynacat/widget-schema.go b/internal/dynacat/widget-schema.go index 78be66d..855ddd8 100644 --- a/internal/dynacat/widget-schema.go +++ b/internal/dynacat/widget-schema.go @@ -134,6 +134,9 @@ var itemAdvancedFields = map[string]bool{ const maxListDepth = 2 var fieldAnnotations = map[string]map[string]fieldAnnotation{ + "bookmarks": { + "style": {Options: []string{"grid"}}, + }, "calendar": { "first-day-of-week": {Options: []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"}}, "hosts.url": {Hint: "Prefix with the service, e.g. sonarr:https://... or radarr:https://..."},