Packages
phoenix_kit
1.7.199
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/phoenix_kit/install/daisyui.ex
defmodule PhoenixKit.Install.DaisyUI do
@moduledoc """
Advisory check of the host's vendored daisyUI version.
PhoenixKit's UI is styled by daisyUI, which lives in the HOST app
(`assets/vendor/daisyui.js` + `daisyui-theme.js`, scaffolded by
`mix phx.new` and loaded from the host's `app.css`). The host owns that
file — PhoenixKit does not manage or replace it; it only **checks** it.
`mix phoenix_kit.install`, `mix phoenix_kit.update`, and
`mix phoenix_kit.doctor` warn when the vendored copy is older than
`minimum_version/0`, with upgrade instructions.
Why the minimum matters: daisyUI < 5.1 reserves the modal scrollbar gutter
UNCONDITIONALLY while a modal/drawer is open, which either leaves a phantom
right-edge strip on non-scrolling pages or (when countered) makes content
reflow ~15px around every modal open/close on scrolling pages. daisyUI
≥ 5.1 reserves the gutter only when the page really has a scrollbar
(`rootscrollgutter.css`), so PhoenixKit ships **no** scrollbar-gutter
compensations of its own (removed 2026-07-12) and relies on a modern
daisyUI instead. Hosts on an old copy see daisyUI's stock old behavior
until they upgrade — that's what the warning is for.
"""
# The oldest daisyUI whose modal scrollbar-gutter handling PhoenixKit's
# modals rely on. The upstream fix matured across 5.1.0 → 5.6.x; PhoenixKit
# is verified against 5.6.17, and 5.6.0 is the floor we recommend.
@minimum_version "5.6.0"
@doc "The minimum daisyUI version PhoenixKit's UI is designed against."
@spec minimum_version() :: String.t()
def minimum_version, do: @minimum_version
@doc "The host-side path of the vendored daisyUI plugin."
@spec host_path() :: Path.t()
def host_path, do: Path.join([File.cwd!(), "assets", "vendor", "daisyui.js"])
@doc """
Parse the daisyUI version out of a plugin bundle, or `nil` when the file is
missing or carries no `version = "x.y.z"` marker.
"""
@spec installed_version(Path.t()) :: String.t() | nil
def installed_version(path) do
with {:ok, content} <- File.read(path),
[_, version] <- Regex.run(~r/version = "([\d.]+)"/, content) do
version
else
_ -> nil
end
end
@doc """
Check the host's vendored daisyUI against `minimum_version/0`.
- `:ok` — present and at/above the minimum
- `{:outdated, version}` — present but older than the minimum
- `:unversioned` — present but carries no parseable version marker
- `:missing` — no `assets/vendor/daisyui.js` (npm or custom setup)
"""
@spec check() :: :ok | {:outdated, String.t()} | :unversioned | :missing
def check do
path = host_path()
cond do
not File.exists?(path) ->
:missing
version = installed_version(path) ->
if outdated?(version), do: {:outdated, version}, else: :ok
true ->
:unversioned
end
end
@doc "Whether a daisyUI version string is below `minimum_version/0`."
@spec outdated?(String.t()) :: boolean()
def outdated?(version) when is_binary(version) do
case {Version.parse(version), Version.parse(@minimum_version)} do
{{:ok, installed}, {:ok, minimum}} -> Version.compare(installed, minimum) == :lt
# Unparseable → don't claim it's outdated; check/0 reports :unversioned.
_ -> false
end
end
@doc "Human warning for an outdated vendored daisyUI, with upgrade steps."
@spec outdated_warning(String.t()) :: String.t()
def outdated_warning(version) do
"""
⚠️ Your vendored daisyUI is #{version}; PhoenixKit is designed against #{@minimum_version}+.
On daisyUI < 5.1, opening any modal/drawer mishandles the scrollbar gutter
(a phantom right-edge strip, or content shifting ~15px on scrolling pages).
Update the two files in assets/vendor/ and rebuild assets:
cd assets/vendor
curl -sLO https://github.com/saadeghi/daisyui/releases/latest/download/daisyui.js
curl -sLO https://github.com/saadeghi/daisyui/releases/latest/download/daisyui-theme.js
Changelog: https://daisyui.com/docs/changelog/
"""
end
end