clowk-phlex 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/clowk/phlex/charts/card.rb +518 -0
- data/lib/clowk/phlex/charts/chart_shape.rb +86 -0
- data/lib/clowk/phlex/charts/display_settings.rb +121 -0
- data/lib/clowk/phlex/charts/format.rb +48 -0
- data/lib/clowk/phlex/charts/gauge_linear.rb +143 -0
- data/lib/clowk/phlex/charts/gauge_radial.rb +82 -0
- data/lib/clowk/phlex/charts/interval_picker.rb +117 -0
- data/lib/clowk/phlex/charts/number_card.rb +365 -0
- data/lib/clowk/phlex/charts/range_picker.rb +176 -0
- data/lib/clowk/phlex/charts/sparkline.rb +261 -0
- data/lib/clowk/phlex/charts/time_series.rb +1058 -0
- data/lib/clowk/phlex/charts/type_picker.rb +109 -0
- data/lib/clowk/phlex/charts/web_time.rb +31 -0
- data/lib/clowk/phlex/component.rb +38 -0
- data/lib/clowk/phlex/ui/icons.rb +24 -0
- data/lib/clowk/phlex/ui/switch.rb +33 -0
- data/lib/clowk/phlex/version.rb +10 -0
- data/lib/clowk/phlex.rb +45 -0
- data/lib/clowk-phlex.rb +4 -0
- data/styles/clowk-phlex.css +156 -0
- metadata +141 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Components::Metrics::ChartTypePicker — dropdown that switches how the metric
|
|
4
|
+
# is drawn: Area (time-series line+fill), Radial (semicircle gauge), or Linear
|
|
5
|
+
# (capacity bar gauge). Same DS dropdown chrome as IntervalPicker/MetricPicker
|
|
6
|
+
# so the modal toolbar reads as a consistent row of pickers.
|
|
7
|
+
#
|
|
8
|
+
# Why it exists: chart_type used to stick to whatever the panel opened as, with
|
|
9
|
+
# no way to change it in the modal — open a gauge, switch metric/pod, and it
|
|
10
|
+
# stayed a gauge. This gives the operator explicit control.
|
|
11
|
+
#
|
|
12
|
+
# URL contract: the active type lives in the `chart_type` query param. `area`
|
|
13
|
+
# is the default and is OMITTED (clean URLs), so the param only appears once
|
|
14
|
+
# the operator picks a gauge. Gauges silently fall back to area for metrics
|
|
15
|
+
# without a percentage/capacity ceiling (same as ChartCard), so all three are
|
|
16
|
+
# always offerable.
|
|
17
|
+
class Clowk::Phlex::Charts::TypePicker < Clowk::Phlex::Component
|
|
18
|
+
DEFAULT = "area"
|
|
19
|
+
|
|
20
|
+
# The type list + labels + glyphs are Clowk::Phlex::Charts::ChartShape's — one
|
|
21
|
+
# source of truth shared with the dashboard builder's shape chips.
|
|
22
|
+
OPTIONS = Clowk::Phlex::Charts::ChartShape::METRIC_TYPES
|
|
23
|
+
LABELS = Clowk::Phlex::Charts::ChartShape::LABELS
|
|
24
|
+
|
|
25
|
+
# current: active chart_type (e.g. "area", "gauge_radial")
|
|
26
|
+
# base_path: URL each row hits (metrics_path or metrics_chart_path)
|
|
27
|
+
# extra_params: merged into every URL EXCEPT `chart_type` (the picker owns
|
|
28
|
+
# it per row). Pass the request query minus `chart_type`.
|
|
29
|
+
# turbo_stream: emit data-turbo-stream so the swap stays modal-local.
|
|
30
|
+
def initialize(current:, base_path:, extra_params: {}, turbo_stream: false)
|
|
31
|
+
@current = current.to_s.presence || DEFAULT
|
|
32
|
+
@base_path = base_path
|
|
33
|
+
@extra_params = extra_params || {}
|
|
34
|
+
@turbo_stream = turbo_stream
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def view_template
|
|
38
|
+
div(class: "relative", data: {controller: "dropdown"}) do
|
|
39
|
+
trigger
|
|
40
|
+
menu
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def trigger
|
|
47
|
+
button(
|
|
48
|
+
type: "button",
|
|
49
|
+
data: {action: "click->dropdown#toggle"},
|
|
50
|
+
class: "inline-flex items-center gap-2 px-2.5 h-9 min-w-[130px] border border-clowk-border bg-clowk-surface text-clowk-text text-[12.5px] hover:bg-clowk-surface-2"
|
|
51
|
+
) do
|
|
52
|
+
render Clowk::Phlex::Charts::ChartShape.new(type: @current, css: "w-5 h-4 shrink-0 text-clowk-muted")
|
|
53
|
+
|
|
54
|
+
span(class: "min-w-0 truncate") do
|
|
55
|
+
span(class: "text-clowk-muted") { "type " }
|
|
56
|
+
span(class: "text-clowk-text") { LABELS[@current] || "Area" }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
div(class: "flex-1")
|
|
60
|
+
icon(:chevron_down, class: "w-2.5 h-2.5 text-clowk-muted")
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def menu
|
|
65
|
+
div(
|
|
66
|
+
hidden: true,
|
|
67
|
+
data: {dropdown_target: "menu"},
|
|
68
|
+
class: "absolute left-0 top-[calc(100%+4px)] z-30 min-w-[150px] border border-clowk-border-2 bg-clowk-surface shadow-2xl"
|
|
69
|
+
) do
|
|
70
|
+
OPTIONS.each { |t| option_row(t[:value], t[:label]) }
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def option_row(value, label)
|
|
75
|
+
active = value == @current
|
|
76
|
+
|
|
77
|
+
a(
|
|
78
|
+
href: build_url(value),
|
|
79
|
+
data: @turbo_stream ? {turbo_stream: "true"} : {turbo: false},
|
|
80
|
+
class: tokens(
|
|
81
|
+
"flex items-center gap-2.5 w-full px-3 py-2 min-h-[34px] text-left",
|
|
82
|
+
active ? "bg-clowk-accent-dim text-clowk-accent-2" : "text-clowk-text hover:bg-clowk-hover"
|
|
83
|
+
)
|
|
84
|
+
) do
|
|
85
|
+
render Clowk::Phlex::Charts::ChartShape.new(type: value, css: "w-6 h-4 shrink-0")
|
|
86
|
+
|
|
87
|
+
span(
|
|
88
|
+
class: tokens(
|
|
89
|
+
"text-[12.5px] truncate flex-1",
|
|
90
|
+
active ? "font-semibold text-clowk-accent-2" : "font-medium text-clowk-text"
|
|
91
|
+
)
|
|
92
|
+
) { label }
|
|
93
|
+
|
|
94
|
+
if active
|
|
95
|
+
icon(:check, class: "w-3 h-3 text-clowk-accent-2 shrink-0 ml-1")
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# build_url — override `chart_type`, leave the rest untouched. `area` is
|
|
101
|
+
# OMITTED so switching back to the default drops the param entirely.
|
|
102
|
+
def build_url(value)
|
|
103
|
+
params = @extra_params.dup
|
|
104
|
+
params[:chart_type] = value unless value == DEFAULT
|
|
105
|
+
|
|
106
|
+
qs = params.to_query
|
|
107
|
+
qs.empty? ? @base_path.to_s : "#{@base_path}?#{qs}"
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Clowk
|
|
4
|
+
module Phlex
|
|
5
|
+
module Charts
|
|
6
|
+
# WebTime — the single "render this moment in the app's timezone" seam for
|
|
7
|
+
# the chart x-axis + tooltips. Uses ActiveSupport's Time.zone when present
|
|
8
|
+
# (Rails hosts), else falls back to UTC — so the lib works with or without
|
|
9
|
+
# Rails, and a host can retune the zone in one place later.
|
|
10
|
+
module WebTime
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
DEFAULT_ZONE_NAME = "UTC"
|
|
14
|
+
|
|
15
|
+
def zone_name
|
|
16
|
+
(defined?(Time.zone) && Time.zone&.name) || DEFAULT_ZONE_NAME
|
|
17
|
+
rescue
|
|
18
|
+
DEFAULT_ZONE_NAME
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# strftime — format a moment (Time / TimeWithZone). Never raises: returns
|
|
22
|
+
# nil on bad input so views render "—" instead of 500-ing.
|
|
23
|
+
def strftime(time, pattern)
|
|
24
|
+
time&.strftime(pattern)
|
|
25
|
+
rescue
|
|
26
|
+
nil
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Clowk
|
|
4
|
+
module Phlex
|
|
5
|
+
# Component is the root Phlex class every clowk-phlex component inherits from.
|
|
6
|
+
# Kept intentionally thin so the lib renders standalone (no Rails required for
|
|
7
|
+
# the pure-view components). Rails view helpers (routes, form_with) are mixed
|
|
8
|
+
# into the specific components that need them, not forced on every subclass.
|
|
9
|
+
#
|
|
10
|
+
# NOTE: `::Phlex::HTML` is fully qualified — inside `Clowk`, the bare `Phlex`
|
|
11
|
+
# would resolve to `Clowk::Phlex`, not the phlex gem.
|
|
12
|
+
class Component < ::Phlex::HTML
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
# icon — render a vendored Heroicon (outline) by name. Replaces the
|
|
16
|
+
# PhlexIcons dependency; extra attrs (class:, aria, …) flow to the <svg>.
|
|
17
|
+
#
|
|
18
|
+
# icon(:ellipsis_vertical, class: "w-4 h-4")
|
|
19
|
+
def icon(name, **attrs)
|
|
20
|
+
d = Clowk::Phlex::UI::Icons::PATHS.fetch(name.to_sym) do
|
|
21
|
+
raise ArgumentError, "unknown clowk icon: #{name.inspect}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
svg(
|
|
25
|
+
xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24",
|
|
26
|
+
"stroke-width": "1.5", stroke: "currentColor", "aria-hidden": "true", **attrs
|
|
27
|
+
) { |s| s.path("stroke-linecap": "round", "stroke-linejoin": "round", d: d) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# tokens — merge CSS class strings, dropping nil / false / empty, so call
|
|
31
|
+
# sites can write `tokens("px-3", active && "bg-clowk-accent-dim")` without
|
|
32
|
+
# the compact+join dance.
|
|
33
|
+
def tokens(*classes)
|
|
34
|
+
classes.flatten.compact.reject { |c| c == false || c == "" }.join(" ").squeeze(" ").strip
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Clowk
|
|
4
|
+
module Phlex
|
|
5
|
+
module UI
|
|
6
|
+
# Icons — the small set of Heroicons (outline, MIT) the components use,
|
|
7
|
+
# vendored so the gem carries no icon dependency. Rendered by the
|
|
8
|
+
# Component#icon helper. Add a path here to use a new glyph.
|
|
9
|
+
#
|
|
10
|
+
# Source: https://heroicons.com (24×24 outline, stroke currentColor).
|
|
11
|
+
module Icons
|
|
12
|
+
PATHS = {
|
|
13
|
+
ellipsis_vertical: "M12 6.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5ZM12 12.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5ZM12 18.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Z",
|
|
14
|
+
arrows_pointing_out: "M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15",
|
|
15
|
+
check: "m4.5 12.75 6 6 9-13.5",
|
|
16
|
+
chevron_down: "m19.5 8.25-7.5 7.5-7.5-7.5",
|
|
17
|
+
calendar_days: "M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 0 1 2.25-2.25h13.5A2.25 2.25 0 0 1 21 7.5v11.25m-18 0A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75m-18 0v-7.5A2.25 2.25 0 0 1 5.25 9h13.5A2.25 2.25 0 0 1 21 11.25v7.5m-9-6h.008v.008H12v-.008ZM12 15h.008v.008H12V15Zm0 2.25h.008v.008H12v-.008ZM9.75 15h.008v.008H9.75V15Zm0 2.25h.008v.008H9.75v-.008ZM7.5 15h.008v.008H7.5V15Zm0 2.25h.008v.008H7.5v-.008Zm6.75-4.5h.008v.008h-.008v-.008Zm0 2.25h.008v.008h-.008V15Zm0 2.25h.008v.008h-.008v-.008Zm2.25-4.5h.008v.008H16.5v-.008Zm0 2.25h.008v.008H16.5V15Z",
|
|
18
|
+
bars_3: "M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5",
|
|
19
|
+
x_mark: "M6 18 18 6M6 6l12 12"
|
|
20
|
+
}.freeze
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Components::UI::Switch — a macOS-style toggle.
|
|
4
|
+
#
|
|
5
|
+
# A visually-hidden (`sr-only`) checkbox is the real control + source of truth
|
|
6
|
+
# (keyboard-focusable, form-serializable, a11y-correct); a Tailwind `peer-checked`
|
|
7
|
+
# track + knob paint the switch on top. Drop-in replacement for a raw checkbox:
|
|
8
|
+
# pass `checked:` plus any input attributes (data:, name:, id:, aria-label:,
|
|
9
|
+
# disabled:, …) and they flow straight through to the <input>.
|
|
10
|
+
#
|
|
11
|
+
# render Components::UI::Switch.new(
|
|
12
|
+
# checked: true,
|
|
13
|
+
# data: { panel_options_target: "dots", action: "change->panel-options#toggleDots" }
|
|
14
|
+
# )
|
|
15
|
+
class Clowk::Phlex::UI::Switch < Clowk::Phlex::Component
|
|
16
|
+
def initialize(checked: false, **attrs)
|
|
17
|
+
@checked = checked
|
|
18
|
+
@attrs = attrs
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def view_template
|
|
22
|
+
span(class: "relative inline-flex items-center shrink-0 w-[34px] h-[20px]") do
|
|
23
|
+
input(
|
|
24
|
+
type: "checkbox", checked: @checked, class: "peer sr-only",
|
|
25
|
+
# type/checked/class are owned by the switch — everything else (data,
|
|
26
|
+
# name, aria, disabled) passes through to the control.
|
|
27
|
+
**@attrs.except(:type, :checked, :class)
|
|
28
|
+
)
|
|
29
|
+
span(class: "absolute inset-0 rounded-full bg-clowk-border transition-colors peer-checked:bg-clowk-accent")
|
|
30
|
+
span(class: "absolute left-[3px] top-[3px] w-[14px] h-[14px] rounded-full bg-white shadow transition-transform peer-checked:translate-x-[14px]")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Synced from the repo-root /VERSION by scripts/sync-version.sh (dev + release CI).
|
|
4
|
+
# The gem and the @clowk/phlex npm package share this version — do not edit by
|
|
5
|
+
# hand; bump /VERSION and re-run the script.
|
|
6
|
+
module Clowk
|
|
7
|
+
module Phlex
|
|
8
|
+
VERSION = "0.1.0"
|
|
9
|
+
end
|
|
10
|
+
end
|
data/lib/clowk/phlex.rb
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "time"
|
|
4
|
+
require "json"
|
|
5
|
+
require "digest"
|
|
6
|
+
require "phlex"
|
|
7
|
+
require "active_support/core_ext/object/blank"
|
|
8
|
+
require "active_support/core_ext/object/to_query"
|
|
9
|
+
|
|
10
|
+
module Clowk
|
|
11
|
+
# Clowk::Phlex — the UI component library namespace. `include Clowk::Phlex` in a
|
|
12
|
+
# view to get the short names (`Charts::Card`, `UI::Dropdown`) via ancestor
|
|
13
|
+
# constant lookup; the `Charts::` / `UI::` prefix is kept on purpose so nothing
|
|
14
|
+
# collides with the host app's own `Card` / `Button`.
|
|
15
|
+
module Phlex
|
|
16
|
+
module Charts; end
|
|
17
|
+
module UI; end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
require_relative "phlex/version"
|
|
22
|
+
require_relative "phlex/component"
|
|
23
|
+
require_relative "phlex/charts/format"
|
|
24
|
+
require_relative "phlex/charts/web_time"
|
|
25
|
+
|
|
26
|
+
# UI atoms
|
|
27
|
+
require_relative "phlex/ui/icons"
|
|
28
|
+
require_relative "phlex/ui/switch"
|
|
29
|
+
|
|
30
|
+
# Chart primitives
|
|
31
|
+
require_relative "phlex/charts/chart_shape"
|
|
32
|
+
require_relative "phlex/charts/sparkline"
|
|
33
|
+
require_relative "phlex/charts/gauge_radial"
|
|
34
|
+
require_relative "phlex/charts/gauge_linear"
|
|
35
|
+
require_relative "phlex/charts/time_series"
|
|
36
|
+
|
|
37
|
+
# Chart assemblies (compose the primitives above)
|
|
38
|
+
require_relative "phlex/charts/card"
|
|
39
|
+
require_relative "phlex/charts/number_card"
|
|
40
|
+
|
|
41
|
+
# Dashboard controls (host injects the URLs / base paths)
|
|
42
|
+
require_relative "phlex/charts/range_picker"
|
|
43
|
+
require_relative "phlex/charts/interval_picker"
|
|
44
|
+
require_relative "phlex/charts/type_picker"
|
|
45
|
+
require_relative "phlex/charts/display_settings"
|
data/lib/clowk-phlex.rb
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* clowk-phlex design tokens.
|
|
3
|
+
*
|
|
4
|
+
* Two layers:
|
|
5
|
+
* 1. :root (+ [data-theme="light"]) define the raw palette --clowk-* — the
|
|
6
|
+
* values a HOST overrides to retheme. Components reference these directly
|
|
7
|
+
* inside SVG / inline styles (e.g. var(--clowk-border)).
|
|
8
|
+
* 2. @theme re-maps them to --color-* / --radius-* / --font-* so Tailwind v4
|
|
9
|
+
* generates the utilities the components use (bg-clowk-*, text-clowk-*,
|
|
10
|
+
* rounded-clowk-*, font-clowk-*).
|
|
11
|
+
*
|
|
12
|
+
* This file is the SOURCE. The npm build precompiles it (scanning the gem's
|
|
13
|
+
* components) into dist/clowk-phlex.css so consumers import a ready stylesheet
|
|
14
|
+
* with no Tailwind @source of their own.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
:root {
|
|
18
|
+
/* Surfaces */
|
|
19
|
+
--clowk-bg: #0b0a0c;
|
|
20
|
+
--clowk-bg-2: #0d0c0f;
|
|
21
|
+
--clowk-surface: #121116;
|
|
22
|
+
--clowk-surface-2: #161419;
|
|
23
|
+
--clowk-surface-3: #1e1b23;
|
|
24
|
+
--clowk-surface-side: #0d0c0f;
|
|
25
|
+
|
|
26
|
+
/* Borders */
|
|
27
|
+
--clowk-border: #201d26;
|
|
28
|
+
--clowk-border-2: #33303b;
|
|
29
|
+
|
|
30
|
+
/* Text */
|
|
31
|
+
--clowk-text: #f4f1ee;
|
|
32
|
+
--clowk-text-2: #c9c4cf;
|
|
33
|
+
--clowk-muted: #8a8592;
|
|
34
|
+
--clowk-muted-2: #57525f;
|
|
35
|
+
|
|
36
|
+
/* Accent */
|
|
37
|
+
--clowk-accent: #5b8def;
|
|
38
|
+
--clowk-accent-2: #84a9f4;
|
|
39
|
+
--clowk-accent-dim: #5b8def26;
|
|
40
|
+
--clowk-accent-line: #5b8def66;
|
|
41
|
+
|
|
42
|
+
/* Cream (primary button fill) */
|
|
43
|
+
--clowk-cream: #f4f1ee;
|
|
44
|
+
--clowk-cream-2: #e6e2dd;
|
|
45
|
+
--clowk-on-cream: #14121a;
|
|
46
|
+
|
|
47
|
+
/* Status */
|
|
48
|
+
--clowk-green: #3fd08c;
|
|
49
|
+
--clowk-green-dim: #3fd08c26;
|
|
50
|
+
--clowk-amber: #e8b24b;
|
|
51
|
+
--clowk-amber-dim: #e8b24b26;
|
|
52
|
+
--clowk-red: #e0574b;
|
|
53
|
+
--clowk-red-dim: #e0574b26;
|
|
54
|
+
--clowk-blue: #7e97ff;
|
|
55
|
+
|
|
56
|
+
/* Extended series palette */
|
|
57
|
+
--clowk-teal: #3fd08c;
|
|
58
|
+
--clowk-cyan: #4fc3d9;
|
|
59
|
+
--clowk-indigo: #7e97ff;
|
|
60
|
+
--clowk-orange: #e8b24b;
|
|
61
|
+
--clowk-pink: #e06bb0;
|
|
62
|
+
--clowk-purple: #b36cf6;
|
|
63
|
+
--clowk-violet: #b36cf6;
|
|
64
|
+
|
|
65
|
+
/* Radius */
|
|
66
|
+
--clowk-r-sm: 3px;
|
|
67
|
+
--clowk-r-md: 9px;
|
|
68
|
+
--clowk-r-lg: 14px;
|
|
69
|
+
|
|
70
|
+
/* Utility */
|
|
71
|
+
--clowk-hover: #ffffff0a;
|
|
72
|
+
--clowk-mix-fg: #ffffff;
|
|
73
|
+
--clowk-on-accent: #ffffff;
|
|
74
|
+
|
|
75
|
+
/* Shadows */
|
|
76
|
+
--clowk-shadow-sm: 0 2px 5px rgba(0, 0, 0, 0.55);
|
|
77
|
+
--clowk-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.55);
|
|
78
|
+
|
|
79
|
+
/* Type */
|
|
80
|
+
--clowk-font-sans: "Hanken Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
|
|
81
|
+
--clowk-font-display: "Space Grotesk", "Hanken Grotesk", ui-sans-serif, system-ui, sans-serif;
|
|
82
|
+
--clowk-font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
|
|
83
|
+
--clowk-font-size-base: 14px;
|
|
84
|
+
--clowk-line-height: 1.45;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
:root[data-theme="light"] {
|
|
88
|
+
--clowk-bg: #f5f3f0;
|
|
89
|
+
--clowk-bg-2: #efede9;
|
|
90
|
+
--clowk-surface: #ffffff;
|
|
91
|
+
--clowk-surface-2: #f6f4f1;
|
|
92
|
+
--clowk-surface-3: #edeae6;
|
|
93
|
+
--clowk-surface-side: #faf9f7;
|
|
94
|
+
|
|
95
|
+
--clowk-border: #e4e0da;
|
|
96
|
+
--clowk-border-2: #d3cec6;
|
|
97
|
+
|
|
98
|
+
--clowk-text: #1a1820;
|
|
99
|
+
--clowk-text-2: #45414c;
|
|
100
|
+
--clowk-muted: #6d6875;
|
|
101
|
+
--clowk-muted-2: #948f9c;
|
|
102
|
+
|
|
103
|
+
--clowk-accent: #3f6fd6;
|
|
104
|
+
--clowk-accent-2: #2c55b8;
|
|
105
|
+
--clowk-accent-dim: #3f6fd618;
|
|
106
|
+
--clowk-accent-line: #3f6fd655;
|
|
107
|
+
|
|
108
|
+
--clowk-cream: #1a1820;
|
|
109
|
+
--clowk-cream-2: #33303b;
|
|
110
|
+
--clowk-on-cream: #ffffff;
|
|
111
|
+
|
|
112
|
+
--clowk-hover: #0000000a;
|
|
113
|
+
--clowk-mix-fg: #000000;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Tailwind v4 mapping — the color / radius / font utilities read these tokens,
|
|
117
|
+
* which point back at the raw palette above. Override --clowk-* to retheme. */
|
|
118
|
+
@theme {
|
|
119
|
+
--color-clowk-bg: var(--clowk-bg);
|
|
120
|
+
--color-clowk-bg-2: var(--clowk-bg-2);
|
|
121
|
+
--color-clowk-surface: var(--clowk-surface);
|
|
122
|
+
--color-clowk-surface-2: var(--clowk-surface-2);
|
|
123
|
+
--color-clowk-surface-3: var(--clowk-surface-3);
|
|
124
|
+
--color-clowk-surface-side: var(--clowk-surface-side);
|
|
125
|
+
--color-clowk-border: var(--clowk-border);
|
|
126
|
+
--color-clowk-border-2: var(--clowk-border-2);
|
|
127
|
+
--color-clowk-text: var(--clowk-text);
|
|
128
|
+
--color-clowk-text-2: var(--clowk-text-2);
|
|
129
|
+
--color-clowk-muted: var(--clowk-muted);
|
|
130
|
+
--color-clowk-muted-2: var(--clowk-muted-2);
|
|
131
|
+
--color-clowk-accent: var(--clowk-accent);
|
|
132
|
+
--color-clowk-accent-2: var(--clowk-accent-2);
|
|
133
|
+
--color-clowk-accent-dim: var(--clowk-accent-dim);
|
|
134
|
+
--color-clowk-accent-line: var(--clowk-accent-line);
|
|
135
|
+
--color-clowk-cream: var(--clowk-cream);
|
|
136
|
+
--color-clowk-cream-2: var(--clowk-cream-2);
|
|
137
|
+
--color-clowk-on-cream: var(--clowk-on-cream);
|
|
138
|
+
--color-clowk-green: var(--clowk-green);
|
|
139
|
+
--color-clowk-green-dim: var(--clowk-green-dim);
|
|
140
|
+
--color-clowk-amber: var(--clowk-amber);
|
|
141
|
+
--color-clowk-amber-dim: var(--clowk-amber-dim);
|
|
142
|
+
--color-clowk-red: var(--clowk-red);
|
|
143
|
+
--color-clowk-red-dim: var(--clowk-red-dim);
|
|
144
|
+
--color-clowk-blue: var(--clowk-blue);
|
|
145
|
+
--color-clowk-purple: var(--clowk-purple);
|
|
146
|
+
--color-clowk-pink: var(--clowk-pink);
|
|
147
|
+
--color-clowk-hover: var(--clowk-hover);
|
|
148
|
+
|
|
149
|
+
--radius-clowk-sm: var(--clowk-r-sm);
|
|
150
|
+
--radius-clowk-md: var(--clowk-r-md);
|
|
151
|
+
--radius-clowk-lg: var(--clowk-r-lg);
|
|
152
|
+
|
|
153
|
+
--font-clowk-sans: var(--clowk-font-sans);
|
|
154
|
+
--font-clowk-display: var(--clowk-font-display);
|
|
155
|
+
--font-clowk-mono: var(--clowk-font-mono);
|
|
156
|
+
}
|
metadata
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: clowk-phlex
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Thadeu Esteves
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-07-13 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activesupport
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '9'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '7.0'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '9'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: phlex
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - "~>"
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '2.0'
|
|
39
|
+
type: :runtime
|
|
40
|
+
prerelease: false
|
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - "~>"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '2.0'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: rake
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - "~>"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '13.0'
|
|
53
|
+
type: :development
|
|
54
|
+
prerelease: false
|
|
55
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - "~>"
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '13.0'
|
|
60
|
+
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: rspec
|
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
|
63
|
+
requirements:
|
|
64
|
+
- - "~>"
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: '3.13'
|
|
67
|
+
type: :development
|
|
68
|
+
prerelease: false
|
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - "~>"
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '3.13'
|
|
74
|
+
- !ruby/object:Gem::Dependency
|
|
75
|
+
name: standard
|
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - "~>"
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: '1.0'
|
|
81
|
+
type: :development
|
|
82
|
+
prerelease: false
|
|
83
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - "~>"
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '1.0'
|
|
88
|
+
description: 'The Ruby half of clowk-phlex: Phlex view components (charts, gauges,
|
|
89
|
+
pickers) that render SVG/HTML markup + data-* attributes. Behavior and styles ship
|
|
90
|
+
via the companion @clowk/phlex npm package.'
|
|
91
|
+
email:
|
|
92
|
+
- tadeuu@gmail.com
|
|
93
|
+
executables: []
|
|
94
|
+
extensions: []
|
|
95
|
+
extra_rdoc_files: []
|
|
96
|
+
files:
|
|
97
|
+
- lib/clowk-phlex.rb
|
|
98
|
+
- lib/clowk/phlex.rb
|
|
99
|
+
- lib/clowk/phlex/charts/card.rb
|
|
100
|
+
- lib/clowk/phlex/charts/chart_shape.rb
|
|
101
|
+
- lib/clowk/phlex/charts/display_settings.rb
|
|
102
|
+
- lib/clowk/phlex/charts/format.rb
|
|
103
|
+
- lib/clowk/phlex/charts/gauge_linear.rb
|
|
104
|
+
- lib/clowk/phlex/charts/gauge_radial.rb
|
|
105
|
+
- lib/clowk/phlex/charts/interval_picker.rb
|
|
106
|
+
- lib/clowk/phlex/charts/number_card.rb
|
|
107
|
+
- lib/clowk/phlex/charts/range_picker.rb
|
|
108
|
+
- lib/clowk/phlex/charts/sparkline.rb
|
|
109
|
+
- lib/clowk/phlex/charts/time_series.rb
|
|
110
|
+
- lib/clowk/phlex/charts/type_picker.rb
|
|
111
|
+
- lib/clowk/phlex/charts/web_time.rb
|
|
112
|
+
- lib/clowk/phlex/component.rb
|
|
113
|
+
- lib/clowk/phlex/ui/icons.rb
|
|
114
|
+
- lib/clowk/phlex/ui/switch.rb
|
|
115
|
+
- lib/clowk/phlex/version.rb
|
|
116
|
+
- styles/clowk-phlex.css
|
|
117
|
+
homepage: https://github.com/clowk/clowk-phlex
|
|
118
|
+
licenses:
|
|
119
|
+
- MIT
|
|
120
|
+
metadata:
|
|
121
|
+
homepage_uri: https://github.com/clowk/clowk-phlex
|
|
122
|
+
source_code_uri: https://github.com/clowk/clowk-phlex/tree/main/gem
|
|
123
|
+
changelog_uri: https://github.com/clowk/clowk-phlex/blob/main/CHANGELOG.md
|
|
124
|
+
rdoc_options: []
|
|
125
|
+
require_paths:
|
|
126
|
+
- lib
|
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '3.2'
|
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
|
+
requirements:
|
|
134
|
+
- - ">="
|
|
135
|
+
- !ruby/object:Gem::Version
|
|
136
|
+
version: '0'
|
|
137
|
+
requirements: []
|
|
138
|
+
rubygems_version: 3.6.2
|
|
139
|
+
specification_version: 4
|
|
140
|
+
summary: Phlex UI components with Stimulus behaviors — charts first.
|
|
141
|
+
test_files: []
|