tuile 0.5.0 → 0.7.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,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tuile
4
+ # An app's theme definition: the {Theme} pair covering both terminal
5
+ # appearances. {Screen} keeps one at {Screen#theme_def} (defaulting to
6
+ # {DEFAULT}) and picks the member matching the detected background at
7
+ # startup and on every OS appearance flip (mode 2031) — so a custom
8
+ # definition survives the user toggling light/dark, where a bare
9
+ # {Screen#theme=} assignment would be replaced.
10
+ #
11
+ # APP_THEME = Tuile::ThemeDef.new(
12
+ # dark: Tuile::Theme::DARK.with(custom: { accent: Color::DARK_ORANGE }),
13
+ # light: Tuile::Theme::LIGHT.with(custom: { accent: Color::DARK_ORANGE3 })
14
+ # )
15
+ # screen.theme_def = APP_THEME
16
+ #
17
+ # Both members must declare the same {Theme#custom} key set. Without
18
+ # that, a token present only in one member would raise `KeyError` at
19
+ # the unpredictable moment the user flips OS appearance; checking here
20
+ # turns it into an immediate construction-time failure.
21
+ #
22
+ # @!attribute [r] dark
23
+ # The theme applied on dark terminal backgrounds.
24
+ # @return [Theme]
25
+ # @!attribute [r] light
26
+ # The theme applied on light terminal backgrounds.
27
+ # @return [Theme]
28
+ class ThemeDef < Data.define(:dark, :light)
29
+ # @param dark [Theme]
30
+ # @param light [Theme]
31
+ # @raise [TypeError] when a member is not a {Theme}.
32
+ # @raise [ArgumentError] when the members' {Theme#custom} key sets differ.
33
+ def initialize(dark:, light:)
34
+ raise TypeError, "dark must be a Tuile::Theme, got #{dark.inspect}" unless dark.is_a?(Theme)
35
+ raise TypeError, "light must be a Tuile::Theme, got #{light.inspect}" unless light.is_a?(Theme)
36
+
37
+ if dark.custom.keys.sort != light.custom.keys.sort
38
+ raise ArgumentError,
39
+ "dark and light must declare the same custom tokens; " \
40
+ "dark has #{dark.custom.keys.sort.inspect}, light has #{light.custom.keys.sort.inspect}"
41
+ end
42
+
43
+ super
44
+ end
45
+
46
+ # The member for the given color scheme. Anything other than `:light`
47
+ # selects {#dark}, matching {TerminalBackground.detect}'s
48
+ # inconclusive-means-dark policy.
49
+ # @param scheme [Symbol] `:dark` or `:light`.
50
+ # @return [Theme]
51
+ def for(scheme) = scheme == :light ? light : dark
52
+
53
+ # The built-in pair: {Theme::DARK} / {Theme::LIGHT}.
54
+ # @return [ThemeDef]
55
+ DEFAULT = new(dark: Theme::DARK, light: Theme::LIGHT)
56
+
57
+ class << self
58
+ # The definition newly-constructed {Screen}s start from (see
59
+ # {Screen#theme_def}); initially {DEFAULT}. Reassigning affects
60
+ # future screens only — an already-constructed screen keeps its
61
+ # definition until {Screen#theme_def=}.
62
+ #
63
+ # Intended for test suites: production apps assign
64
+ # {Screen#theme_def=} once at startup, but component specs build a
65
+ # fresh {FakeScreen} per example, and a component reading a custom
66
+ # token (`theme[:accent]`) would `KeyError` against the built-in
67
+ # default. Point this at the app's definition once and every
68
+ # {Screen.fake} carries it:
69
+ #
70
+ # Tuile::ThemeDef.default = APP_THEME # spec_helper.rb, once
71
+ # before { Screen.fake } # theme[:accent] resolves
72
+ # @return [ThemeDef]
73
+ attr_reader :default
74
+
75
+ # @param theme_def [ThemeDef]
76
+ # @raise [TypeError] when not a {ThemeDef}.
77
+ def default=(theme_def)
78
+ raise TypeError, "expected ThemeDef, got #{theme_def.inspect}" unless theme_def.is_a?(ThemeDef)
79
+
80
+ @default = theme_def
81
+ end
82
+ end
83
+ @default = DEFAULT
84
+ end
85
+ end
data/lib/tuile/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Tuile
4
4
  # @return [String]
5
- VERSION = "0.5.0"
5
+ VERSION = "0.7.0"
6
6
  end
data/lib/tuile.rb CHANGED
@@ -3,7 +3,6 @@
3
3
  require "concurrent"
4
4
  require "io/console"
5
5
  require "logger"
6
- require "rainbow"
7
6
  require "singleton"
8
7
  require "strscan"
9
8
  require "tty-cursor"
data/mise.toml ADDED
@@ -0,0 +1,2 @@
1
+ [tools]
2
+ ruby = "3.3"