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.
@@ -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
@@ -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"
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Entry point for `require "clowk-phlex"` (gem name uses a dash).
4
+ require_relative "clowk/phlex"
@@ -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: []