its-swiss 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/CHANGELOG.md +57 -0
- data/LICENSE +21 -0
- data/README.md +262 -0
- data/app/assets/javascripts/its_swiss/clipboard_controller.js +33 -0
- data/app/assets/stylesheets/its-swiss.css +16 -0
- data/app/assets/stylesheets/its_swiss/components.css +403 -0
- data/app/assets/stylesheets/its_swiss/grid.css +67 -0
- data/app/assets/stylesheets/its_swiss/reset.css +50 -0
- data/app/assets/stylesheets/its_swiss/specimen.css +37 -0
- data/app/assets/stylesheets/its_swiss/tokens.css +142 -0
- data/app/assets/stylesheets/its_swiss/transitions.css +47 -0
- data/app/assets/stylesheets/its_swiss/type.css +109 -0
- data/app/controllers/its_swiss/specimen_controller.rb +24 -0
- data/app/helpers/its_swiss/application_helper.rb +73 -0
- data/app/views/its_swiss/shared/_errors.html.erb +14 -0
- data/app/views/its_swiss/shared/_flash.html.erb +8 -0
- data/app/views/its_swiss/shared/_masthead.html.erb +15 -0
- data/app/views/its_swiss/shared/_pagination.html.erb +26 -0
- data/app/views/its_swiss/specimen/_buttons.html.erb +15 -0
- data/app/views/its_swiss/specimen/_footer.html.erb +7 -0
- data/app/views/its_swiss/specimen/_form.html.erb +18 -0
- data/app/views/its_swiss/specimen/_grid.html.erb +14 -0
- data/app/views/its_swiss/specimen/_masthead.html.erb +15 -0
- data/app/views/its_swiss/specimen/_messages.html.erb +13 -0
- data/app/views/its_swiss/specimen/_pagination.html.erb +4 -0
- data/app/views/its_swiss/specimen/_pairs.html.erb +8 -0
- data/app/views/its_swiss/specimen/_table.html.erb +15 -0
- data/app/views/its_swiss/specimen/_take.html.erb +19 -0
- data/app/views/its_swiss/specimen/_type.html.erb +24 -0
- data/app/views/its_swiss/specimen/_values.html.erb +18 -0
- data/app/views/its_swiss/specimen/show.html.erb +27 -0
- data/app/views/layouts/its_swiss/shell.html.erb +55 -0
- data/config/importmap.rb +5 -0
- data/config/routes.rb +6 -0
- data/lib/generators/its_swiss/install/install_generator.rb +70 -0
- data/lib/generators/its_swiss/install/templates/theme.css +44 -0
- data/lib/its-swiss.rb +3 -0
- data/lib/its_swiss/engine.rb +39 -0
- data/lib/its_swiss/form_builder.rb +140 -0
- data/lib/its_swiss/version.rb +3 -0
- data/lib/its_swiss.rb +46 -0
- metadata +172 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require "rails/generators/base"
|
|
2
|
+
|
|
3
|
+
module ItsSwiss
|
|
4
|
+
module Generators
|
|
5
|
+
# Four things, each of them easy to get wrong by hand and quiet when it is
|
|
6
|
+
# wrong. Everything else the library does is a gem dependency and needs no
|
|
7
|
+
# generator at all: Propshaft finds the stylesheets, and the engine pins
|
|
8
|
+
# its own JavaScript so that upgrading the gem is enough to get the new
|
|
9
|
+
# file.
|
|
10
|
+
class InstallGenerator < Rails::Generators::Base
|
|
11
|
+
source_root File.expand_path("templates", __dir__)
|
|
12
|
+
|
|
13
|
+
desc "Fills in the slots its-swiss leaves for an application: the accent, the typeface, the grid."
|
|
14
|
+
|
|
15
|
+
def create_theme_stylesheet
|
|
16
|
+
template "theme.css", "app/assets/stylesheets/theme.css"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# An application that has already chosen a layout has chosen it.
|
|
20
|
+
def render_through_the_shell
|
|
21
|
+
controller = "app/controllers/application_controller.rb"
|
|
22
|
+
return say_status(:skip, "#{controller} not found", :yellow) unless exists?(controller)
|
|
23
|
+
|
|
24
|
+
contents = read(controller)
|
|
25
|
+
return say_status(:skip, "#{controller} already chooses a layout", :yellow) if contents.match?(/^\s*layout\s/)
|
|
26
|
+
|
|
27
|
+
inject_into_class controller, "ApplicationController", %( layout "its_swiss/shell"\n)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Development only, and the controller refuses it a second time: the
|
|
31
|
+
# specimen names every component the library has, and a route is a line
|
|
32
|
+
# in a file someone can move.
|
|
33
|
+
def mount_the_specimen
|
|
34
|
+
routes = "config/routes.rb"
|
|
35
|
+
return say_status(:skip, "#{routes} not found", :yellow) unless exists?(routes)
|
|
36
|
+
return say_status(:skip, "the specimen is already mounted", :yellow) if read(routes).include?("ItsSwiss::Engine")
|
|
37
|
+
|
|
38
|
+
inject_into_file routes, after: /Rails\.application\.routes\.draw do\n/ do
|
|
39
|
+
<<~RUBY.indent(2)
|
|
40
|
+
if Rails.env.development?
|
|
41
|
+
mount ItsSwiss::Engine => "/its-swiss"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
RUBY
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def say_what_is_left
|
|
49
|
+
say <<~TEXT
|
|
50
|
+
|
|
51
|
+
its-swiss is installed. What is left is yours:
|
|
52
|
+
|
|
53
|
+
app/assets/stylesheets/theme.css the accent, the typeface, the grid
|
|
54
|
+
/its-swiss/specimen every component, rendered twice
|
|
55
|
+
|
|
56
|
+
The library ships no typeface and no palette. Set --accent to one
|
|
57
|
+
colour and read the specimen with it unset: if the page still works,
|
|
58
|
+
the value scale is doing the work.
|
|
59
|
+
TEXT
|
|
60
|
+
end
|
|
61
|
+
private
|
|
62
|
+
# Thor writes relative to destination_root; reading has to as well, or
|
|
63
|
+
# the guards above interrogate whatever directory the generator was
|
|
64
|
+
# invoked from.
|
|
65
|
+
def exists?(path) = File.exist?(File.expand_path(path, destination_root))
|
|
66
|
+
|
|
67
|
+
def read(path) = File.read(File.expand_path(path, destination_root))
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/* What this application fills in.
|
|
2
|
+
*
|
|
3
|
+
* Unlayered on purpose. Everything its-swiss ships is inside a cascade layer,
|
|
4
|
+
* and an unlayered rule beats every layered one whatever its specificity — so
|
|
5
|
+
* this file wins without having to out-specify the library or reach for
|
|
6
|
+
* !important, and the grid and the domain components below it win too.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
:root {
|
|
10
|
+
/* --- The accent --------------------------------------------------------
|
|
11
|
+
State and emphasis only: the current destination, focus, a link, the one
|
|
12
|
+
primary action, the moment before something cannot be undone. Never a
|
|
13
|
+
filled area for its own sake.
|
|
14
|
+
|
|
15
|
+
Delete this line and read the app. If it still works, the value scale is
|
|
16
|
+
doing the work, which is the point. */
|
|
17
|
+
--accent: oklch(57.7% 0.234 28);
|
|
18
|
+
--accent-ink: var(--paper);
|
|
19
|
+
|
|
20
|
+
/* --- The typeface ------------------------------------------------------
|
|
21
|
+
The library ships none. Declare an @font-face below and name it here, or
|
|
22
|
+
leave this out and take the grotesque stack the library falls back to. */
|
|
23
|
+
/* --font-family: "Your Face", ui-sans-serif, system-ui, sans-serif; */
|
|
24
|
+
|
|
25
|
+
/* --- The value scale ---------------------------------------------------
|
|
26
|
+
Neutral as it ships. These two turn the whole ladder together: a small
|
|
27
|
+
chroma at a yellow-green hue gives the warm grays of a printed page. */
|
|
28
|
+
/* --value-chroma: 0.006; */
|
|
29
|
+
/* --value-hue: 95; */
|
|
30
|
+
|
|
31
|
+
/* --- The grid ----------------------------------------------------------
|
|
32
|
+
How many fields this problem has. Six divides into halves and thirds and
|
|
33
|
+
is where the library starts; change it here once the pages have said what
|
|
34
|
+
they need, and every width in the app re-proportions. */
|
|
35
|
+
--columns: 6;
|
|
36
|
+
--gutter: 1.5rem;
|
|
37
|
+
--baseline: 0.5rem;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* The grid itself lives here, not in the gem: which blocks span which fields
|
|
41
|
+
is what this application looks like.
|
|
42
|
+
|
|
43
|
+
main.grid > .page-head { --span: 4; }
|
|
44
|
+
*/
|
data/lib/its-swiss.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require "rails/engine"
|
|
2
|
+
|
|
3
|
+
module ItsSwiss
|
|
4
|
+
# Isolated, so the specimen's routes and helpers cannot collide with the
|
|
5
|
+
# application's. The stylesheets are not isolated by anything — CSS has one
|
|
6
|
+
# global namespace and pretending otherwise would mean prefixing every
|
|
7
|
+
# class in the library.
|
|
8
|
+
class Engine < ::Rails::Engine
|
|
9
|
+
isolate_namespace ItsSwiss
|
|
10
|
+
|
|
11
|
+
# Propshaft picks up an engine's app/assets/stylesheets on its own. The
|
|
12
|
+
# JavaScript is not in that default set, and it is one file, so it is
|
|
13
|
+
# added here rather than left to the application to remember.
|
|
14
|
+
initializer "its_swiss.assets" do |app|
|
|
15
|
+
next unless app.config.respond_to?(:assets)
|
|
16
|
+
|
|
17
|
+
app.config.assets.paths << root.join("app/assets/javascripts")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Pinned from the engine rather than written into the application's
|
|
21
|
+
# importmap by the generator: an application that upgrades the gem should
|
|
22
|
+
# get the new file without re-running a generator, and a pin it never
|
|
23
|
+
# wrote is a pin it cannot leave stale.
|
|
24
|
+
initializer "its_swiss.importmap", before: "importmap" do |app|
|
|
25
|
+
next unless app.respond_to?(:importmap)
|
|
26
|
+
|
|
27
|
+
app.config.importmap.paths << root.join("config/importmap.rb")
|
|
28
|
+
# Reloading in development watches the pinned files for changes; a gem
|
|
29
|
+
# loaded from a path: dependency is being edited, so it is watched too.
|
|
30
|
+
app.config.importmap.cache_sweepers << root.join("app/assets/javascripts")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
config.to_prepare do
|
|
34
|
+
ActiveSupport.on_load(:action_view) do
|
|
35
|
+
include ItsSwiss::ApplicationHelper
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
module ItsSwiss
|
|
2
|
+
# One shape for every field: a label, a control, and — when there is
|
|
3
|
+
# something to say — a hint or the reason it was refused.
|
|
4
|
+
#
|
|
5
|
+
# Written by a builder rather than by hand because the parts that get left
|
|
6
|
+
# out by hand are the parts nobody sees missing. A label whose `for` does not
|
|
7
|
+
# match its input is a label that does not enlarge the target. A hint beside
|
|
8
|
+
# a control is a hint a screen reader never reaches. A refused field coloured
|
|
9
|
+
# by CSS alone is a refusal that only some readers get.
|
|
10
|
+
class FormBuilder < ActionView::Helpers::FormBuilder
|
|
11
|
+
# Everything that is a line of text under a rule. They differ only in the
|
|
12
|
+
# keyboard a phone puts up, which is not a difference the markup has.
|
|
13
|
+
TEXT_FIELDS = %i[
|
|
14
|
+
text_field email_field password_field number_field url_field
|
|
15
|
+
telephone_field phone_field search_field date_field time_field
|
|
16
|
+
datetime_field color_field text_area
|
|
17
|
+
].freeze
|
|
18
|
+
|
|
19
|
+
TEXT_FIELDS.each do |control|
|
|
20
|
+
define_method(control) do |method, options = {}|
|
|
21
|
+
field(method, options) { |opts| super(method, opts) }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def select(method, choices = nil, options = {}, html_options = {}, &block)
|
|
26
|
+
field(method, html_options) do |opts|
|
|
27
|
+
super(method, choices, options, opts, &block)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
|
|
32
|
+
field(method, html_options) do |opts|
|
|
33
|
+
super(method, collection, value_method, text_method, options, opts)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# A checkbox and its label are a pair on one line — the label says what
|
|
38
|
+
# ticking it means, and reading that above an empty box says nothing.
|
|
39
|
+
def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
|
|
40
|
+
field(method, options, label_beside: true) do |opts|
|
|
41
|
+
super(method, opts, checked_value, unchecked_value)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def radio_button(method, tag_value, options = {})
|
|
46
|
+
field(method, options, label_beside: true, label_for_value: tag_value) do |opts|
|
|
47
|
+
super(method, tag_value, opts)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# A <button>, not an <input>: an input's label is an attribute, and the
|
|
52
|
+
# one thing this style asks of a button is that it be a box with words in
|
|
53
|
+
# it. Primary unless the caller says otherwise, because a form has one
|
|
54
|
+
# thing it is for.
|
|
55
|
+
def submit(value = nil, options = {})
|
|
56
|
+
value ||= submit_default_value
|
|
57
|
+
options = { class: "button button--primary" }.merge(options.symbolize_keys)
|
|
58
|
+
|
|
59
|
+
@template.tag.button(value, **options, type: "submit")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# The wrapper on its own, for a control the library does not know about.
|
|
63
|
+
def field(method, options = {}, label_beside: false, label_for_value: nil, &control)
|
|
64
|
+
options = options.symbolize_keys
|
|
65
|
+
hint, label_option = options.delete(:hint), options.delete(:label)
|
|
66
|
+
errors = errors_on(method)
|
|
67
|
+
|
|
68
|
+
ids = describers(method, hint, errors)
|
|
69
|
+
options[:"aria-describedby"] = ids.join(" ") if ids.any?
|
|
70
|
+
options[:"aria-invalid"] = "true" if errors.any?
|
|
71
|
+
|
|
72
|
+
label = rendered_label(method, label_option, label_for_value)
|
|
73
|
+
options[:"aria-label"] ||= default_label(method) if label.nil?
|
|
74
|
+
body = @template.capture { control.call(options) }
|
|
75
|
+
body = @template.tag.span(safe_join([ body, label ]), class: "choice") if label_beside && label
|
|
76
|
+
|
|
77
|
+
@template.tag.div(class: field_classes(errors)) do
|
|
78
|
+
safe_join([
|
|
79
|
+
(label unless label_beside),
|
|
80
|
+
body,
|
|
81
|
+
hint_tag(method, hint),
|
|
82
|
+
*errors.map.with_index { |message, index| error_tag(method, index, message) }
|
|
83
|
+
].compact)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
def field_classes(errors)
|
|
89
|
+
errors.any? ? "field field--invalid" : "field"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# `label: false` hides the label; it does not remove it. Something has to
|
|
93
|
+
# name the control, so the name moves onto the control itself.
|
|
94
|
+
def rendered_label(method, option, for_value)
|
|
95
|
+
return nil if option == false
|
|
96
|
+
|
|
97
|
+
label(method, option.is_a?(String) ? option : nil, value: for_value)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# A control whose label is hidden still needs a name, and aria-label is
|
|
101
|
+
# where it goes. Applied to the control rather than the wrapper because
|
|
102
|
+
# the wrapper is a div and names nothing.
|
|
103
|
+
def describers(method, hint, errors)
|
|
104
|
+
ids = []
|
|
105
|
+
ids << hint_id(method) if hint
|
|
106
|
+
errors.each_index { |index| ids << error_id(method, index) }
|
|
107
|
+
ids
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def hint_tag(method, hint)
|
|
111
|
+
return nil unless hint
|
|
112
|
+
|
|
113
|
+
@template.tag.p(hint, class: "hint", id: hint_id(method))
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def error_tag(method, index, message)
|
|
117
|
+
@template.tag.p(message, class: "field__error", id: error_id(method, index))
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# What the label would have said, for a control whose label is hidden.
|
|
121
|
+
def default_label(method)
|
|
122
|
+
@object_name.to_s.camelize.safe_constantize&.human_attribute_name(method) ||
|
|
123
|
+
method.to_s.humanize
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def hint_id(method) = "#{field_id(method)}_hint"
|
|
127
|
+
|
|
128
|
+
def error_id(method, index) = "#{field_id(method)}_error_#{index}"
|
|
129
|
+
|
|
130
|
+
# Full messages, so "cannot be blank" reads as a sentence about the
|
|
131
|
+
# field rather than as a fragment floating under it.
|
|
132
|
+
def errors_on(method)
|
|
133
|
+
return [] unless @object.respond_to?(:errors)
|
|
134
|
+
|
|
135
|
+
Array(@object.errors.full_messages_for(method))
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def safe_join(parts) = @template.safe_join(parts)
|
|
139
|
+
end
|
|
140
|
+
end
|
data/lib/its_swiss.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require "its_swiss/version"
|
|
2
|
+
require "its_swiss/engine" if defined?(Rails::Engine)
|
|
3
|
+
|
|
4
|
+
module ItsSwiss
|
|
5
|
+
# Autoloaded rather than required: it subclasses ActionView's builder, which
|
|
6
|
+
# does not exist until Action View has loaded, and this file is read while
|
|
7
|
+
# the application is still assembling itself.
|
|
8
|
+
autoload :FormBuilder, "its_swiss/form_builder"
|
|
9
|
+
|
|
10
|
+
# The stylesheets, in the order their layers are declared. The gem's own
|
|
11
|
+
# layer order is fixed here rather than left to whoever writes the <link>
|
|
12
|
+
# tags: an application that loads type before tokens should still get the
|
|
13
|
+
# cascade the library was designed with.
|
|
14
|
+
#
|
|
15
|
+
# Every file states its own layer, so linking these six individually and
|
|
16
|
+
# linking the single its-swiss.css that imports them resolve identically.
|
|
17
|
+
STYLESHEETS = %w[ tokens reset type grid components transitions ].freeze
|
|
18
|
+
|
|
19
|
+
# The cascade layer everything the gem ships lives in. An application's own
|
|
20
|
+
# CSS is unlayered, and unlayered rules beat every layered one regardless of
|
|
21
|
+
# specificity — which is the boundary in the table made mechanical: the gem
|
|
22
|
+
# is a base, and the app's grid and domain components win without anyone
|
|
23
|
+
# having to count selectors or reach for !important.
|
|
24
|
+
LAYER = "its-swiss".freeze
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
# Where a consumer says which of the gem's slots it fills. Nothing here
|
|
28
|
+
# has a default the gem could reasonably pick for it.
|
|
29
|
+
def configure
|
|
30
|
+
yield config
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def config
|
|
34
|
+
@config ||= Configuration.new
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class Configuration
|
|
39
|
+
# The specimen is documentation and a regression fixture, not a page an
|
|
40
|
+
# application serves. It stays off unless the environment asks for it, so
|
|
41
|
+
# a route left mounted by accident cannot answer in production.
|
|
42
|
+
attr_writer :specimen
|
|
43
|
+
|
|
44
|
+
def specimen? = @specimen.nil? ? !!Rails.env.local? : @specimen
|
|
45
|
+
end
|
|
46
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: its-swiss
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Bobby Meyer
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-08-31 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: railties
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '8.0'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '10'
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '8.0'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '10'
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
34
|
+
name: actionview
|
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '8.0'
|
|
40
|
+
- - "<"
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '10'
|
|
43
|
+
type: :runtime
|
|
44
|
+
prerelease: false
|
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
46
|
+
requirements:
|
|
47
|
+
- - ">="
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '8.0'
|
|
50
|
+
- - "<"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '10'
|
|
53
|
+
- !ruby/object:Gem::Dependency
|
|
54
|
+
name: propshaft
|
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '1.0'
|
|
60
|
+
- - "<"
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '3'
|
|
63
|
+
type: :runtime
|
|
64
|
+
prerelease: false
|
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '1.0'
|
|
70
|
+
- - "<"
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '3'
|
|
73
|
+
- !ruby/object:Gem::Dependency
|
|
74
|
+
name: importmap-rails
|
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '2.0'
|
|
80
|
+
- - "<"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '4'
|
|
83
|
+
type: :runtime
|
|
84
|
+
prerelease: false
|
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '2.0'
|
|
90
|
+
- - "<"
|
|
91
|
+
- !ruby/object:Gem::Version
|
|
92
|
+
version: '4'
|
|
93
|
+
description: |-
|
|
94
|
+
Tokens, reset, typography, grid primitives and components in the spirit of
|
|
95
|
+
the International Typographic Style, as plain CSS plus a Rails engine that
|
|
96
|
+
ships it. Monochrome by default: the value scale does the work and the one
|
|
97
|
+
accent is the consuming application's to set.
|
|
98
|
+
email:
|
|
99
|
+
- bobby@bobbymeyer.com
|
|
100
|
+
executables: []
|
|
101
|
+
extensions: []
|
|
102
|
+
extra_rdoc_files: []
|
|
103
|
+
files:
|
|
104
|
+
- CHANGELOG.md
|
|
105
|
+
- LICENSE
|
|
106
|
+
- README.md
|
|
107
|
+
- app/assets/javascripts/its_swiss/clipboard_controller.js
|
|
108
|
+
- app/assets/stylesheets/its-swiss.css
|
|
109
|
+
- app/assets/stylesheets/its_swiss/components.css
|
|
110
|
+
- app/assets/stylesheets/its_swiss/grid.css
|
|
111
|
+
- app/assets/stylesheets/its_swiss/reset.css
|
|
112
|
+
- app/assets/stylesheets/its_swiss/specimen.css
|
|
113
|
+
- app/assets/stylesheets/its_swiss/tokens.css
|
|
114
|
+
- app/assets/stylesheets/its_swiss/transitions.css
|
|
115
|
+
- app/assets/stylesheets/its_swiss/type.css
|
|
116
|
+
- app/controllers/its_swiss/specimen_controller.rb
|
|
117
|
+
- app/helpers/its_swiss/application_helper.rb
|
|
118
|
+
- app/views/its_swiss/shared/_errors.html.erb
|
|
119
|
+
- app/views/its_swiss/shared/_flash.html.erb
|
|
120
|
+
- app/views/its_swiss/shared/_masthead.html.erb
|
|
121
|
+
- app/views/its_swiss/shared/_pagination.html.erb
|
|
122
|
+
- app/views/its_swiss/specimen/_buttons.html.erb
|
|
123
|
+
- app/views/its_swiss/specimen/_footer.html.erb
|
|
124
|
+
- app/views/its_swiss/specimen/_form.html.erb
|
|
125
|
+
- app/views/its_swiss/specimen/_grid.html.erb
|
|
126
|
+
- app/views/its_swiss/specimen/_masthead.html.erb
|
|
127
|
+
- app/views/its_swiss/specimen/_messages.html.erb
|
|
128
|
+
- app/views/its_swiss/specimen/_pagination.html.erb
|
|
129
|
+
- app/views/its_swiss/specimen/_pairs.html.erb
|
|
130
|
+
- app/views/its_swiss/specimen/_table.html.erb
|
|
131
|
+
- app/views/its_swiss/specimen/_take.html.erb
|
|
132
|
+
- app/views/its_swiss/specimen/_type.html.erb
|
|
133
|
+
- app/views/its_swiss/specimen/_values.html.erb
|
|
134
|
+
- app/views/its_swiss/specimen/show.html.erb
|
|
135
|
+
- app/views/layouts/its_swiss/shell.html.erb
|
|
136
|
+
- config/importmap.rb
|
|
137
|
+
- config/routes.rb
|
|
138
|
+
- lib/generators/its_swiss/install/install_generator.rb
|
|
139
|
+
- lib/generators/its_swiss/install/templates/theme.css
|
|
140
|
+
- lib/its-swiss.rb
|
|
141
|
+
- lib/its_swiss.rb
|
|
142
|
+
- lib/its_swiss/engine.rb
|
|
143
|
+
- lib/its_swiss/form_builder.rb
|
|
144
|
+
- lib/its_swiss/version.rb
|
|
145
|
+
homepage: https://github.com/bobbymeyer/its-swiss
|
|
146
|
+
licenses:
|
|
147
|
+
- MIT
|
|
148
|
+
metadata:
|
|
149
|
+
source_code_uri: https://github.com/bobbymeyer/its-swiss
|
|
150
|
+
bug_tracker_uri: https://github.com/bobbymeyer/its-swiss/issues
|
|
151
|
+
changelog_uri: https://github.com/bobbymeyer/its-swiss/blob/main/CHANGELOG.md
|
|
152
|
+
rubygems_mfa_required: 'true'
|
|
153
|
+
post_install_message:
|
|
154
|
+
rdoc_options: []
|
|
155
|
+
require_paths:
|
|
156
|
+
- lib
|
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
158
|
+
requirements:
|
|
159
|
+
- - ">="
|
|
160
|
+
- !ruby/object:Gem::Version
|
|
161
|
+
version: 3.2.0
|
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - ">="
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '0'
|
|
167
|
+
requirements: []
|
|
168
|
+
rubygems_version: 3.5.22
|
|
169
|
+
signing_key:
|
|
170
|
+
specification_version: 4
|
|
171
|
+
summary: A Swiss typographic style for Rails applications.
|
|
172
|
+
test_files: []
|