sun-sword 0.0.9 → 0.0.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac608a5b50200fae69d551c25b6abddc5355da222a1a8da739a7aba7c27fac03
4
- data.tar.gz: 2d9fab48ea8cc5560198a23801e3424683b7a0c236df9b3b13a12bdde468cc29
3
+ metadata.gz: b3549043ef82d7091d8e6d984f86eefaf03ea039f2844f34f2b4f73e308006e1
4
+ data.tar.gz: 7d311b8b6e938425160c8d83d9a4122c7ced6271cec8e361caf91156b407c99b
5
5
  SHA512:
6
- metadata.gz: 1ad02d8c6f6f1f92e2244754dc4fee44d2073af1f071dcb96b67ced1625a432aa4e142b8f06139aef3f491b5b48fee1b7bb3d3f064827e5998b6cae54211958c
7
- data.tar.gz: 400165a8e6d7df364e0ea8ab835cef59cdcdf4ed2b1e707d6084605f2c17df99c5e93b948b47668ee48264bf90ef979ee8e203e8ab3494a0d268722df1057a7f
6
+ metadata.gz: 8d1e7a1946d73a1172608407db3d9edfb29d7832445cbd6eeb75bc648f05934250be28f1bc614b00e757a5984b08cd4ab82b8a22f60c994ad715bf0b21faa523
7
+ data.tar.gz: 9617f1d30d53033195b5387d677c79526db7744550529f51828a3b6470f2aca849b755e666c64190de81121d0e2880fbd0157be400f1789e2ec1a4f0e00f2fbb
data/.rubocop.yml CHANGED
@@ -1,6 +1,14 @@
1
1
  # Omakase Ruby styling for Rails
2
2
  inherit_gem: { rubocop-rails-omakase: rubocop.yml }
3
3
 
4
+ # Load extensions via Plugin API (bukan `require:`)
5
+ plugins:
6
+ - rubocop-rails
7
+ - rubocop-performance
8
+ # tambahkan jika dipakai:
9
+ # - rubocop-rspec
10
+ # - rubocop-minitest
11
+
4
12
  # Overwrite or add rules to create your own house style
5
13
  #
6
14
  # # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
@@ -9,7 +17,7 @@ inherit_gem: { rubocop-rails-omakase: rubocop.yml }
9
17
 
10
18
  AllCops:
11
19
  SuggestExtensions: false
12
- TargetRubyVersion: 3.3.4
20
+ TargetRubyVersion: 3.3
13
21
  DisabledByDefault: true
14
22
  Exclude:
15
23
  - '**/templates/**/*'
@@ -526,9 +534,6 @@ Lint/ShadowedException:
526
534
  Lint/RedundantStringCoercion:
527
535
  Enabled: true
528
536
 
529
- Lint/Syntax:
530
- Enabled: true
531
-
532
537
  Lint/UnderscorePrefixedVariableName:
533
538
  Enabled: true
534
539
 
data/README.md CHANGED
@@ -15,28 +15,17 @@ gem 'sun-sword'
15
15
 
16
16
  And then execute:
17
17
  ```bash
18
- $ rails new kotaro_minami -d=postgresql -T --skip-javascript --skip-asset-pipeline
19
- $ bundle install
20
- $ rails generate rider_kick:init
21
- $ rails generate rider_kick:clean_arch --setup
22
- $ rails db:drop db:create db:migrate db:seed
23
18
  $ rails generate sun_sword:frontend
24
- $ rubocop -a
19
+ $ rubocop -A
25
20
  ```
26
21
  ## Usage
27
22
  ```bash
28
23
  Description:
29
24
  Clean Architecture CRUD generator
30
- rails new kotaro_minami -d=postgresql -T --skip-javascript --skip-asset-pipeline
31
25
 
32
26
  Example:
33
- To Generate Init:
34
- bin/rails generate rider_kick:init
35
-
36
- To Generate Pattern:
37
- bin/rails generate rider_kick:clean_arch --setup
38
-
39
27
  To Generate Frontend:
28
+ bin/rails generate sun_sword:init
40
29
  bin/rails generate sun_sword:frontend --setup
41
30
 
42
31
  To Generate scaffold:
@@ -3,6 +3,7 @@ Description:
3
3
  rails new jendral_jack -d=postgresql -T --skip-javascript --skip-asset-pipeline
4
4
 
5
5
  Example:
6
+ bin/rails generate sun_sword:init
6
7
  bin/rails generate sun_sword:frontend --setup
7
8
  bin/rails generate sun_sword:scaffold contacts<check in db/structure>
8
9
 
@@ -49,6 +49,10 @@ module SunSword
49
49
  gem "turbo-rails"
50
50
  gem "stimulus-rails"
51
51
  gem "vite_rails"
52
+
53
+ group :development do
54
+ gem "listen"
55
+ end
52
56
  RUBY
53
57
  append_to_file('Gemfile', gem_dependencies)
54
58
  say 'Vite Rails gem added and bundle installed', :green
@@ -57,10 +61,9 @@ module SunSword
57
61
  def install_vite
58
62
  template 'package.json', 'package.json'
59
63
  run 'bundle exec vite install'
60
- run 'yarn add -D sass vite-plugin-full-reload vite-plugin-ruby vite-plugin-stimulus-hmr'
61
- run 'yarn add -D tailwindcss @tailwindcss/forms @tailwindcss/typography @tailwindcss/aspect-ratio @tailwindcss/forms @tailwindcss/line-clamp autoprefixer'
62
- run 'yarn add -D eslint prettier eslint-plugin-prettier eslint-config-prettier eslint-plugin-tailwindcss path'
63
- run 'yarn add @hotwired/stimulus @hotwired/turbo-rails stimulus-vite-helpers vite animejs stimulus-use'
64
+ run 'yarn add -D vite vite-plugin-full-reload vite-plugin-ruby vite-plugin-stimulus-hmr'
65
+ run 'yarn add path stimulus-vite-helpers @hotwired/stimulus @hotwired/turbo-rails @tailwindcss/aspect-ratio @tailwindcss/forms @tailwindcss/line-clamp @tailwindcss/typography @tailwindcss/vite tailwindcss vite-plugin-rails autoprefixer'
66
+ run 'yarn add -D eslint prettier eslint-plugin-prettier eslint-config-prettier eslint-plugin-tailwindcss'
64
67
  say 'Vite installed successfully', :green
65
68
  end
66
69
 
@@ -68,8 +71,6 @@ module SunSword
68
71
  say 'Configuring Vite...'
69
72
 
70
73
  # Add a basic Vite configuration file to your Rails app
71
- template 'tailwind.config.js', 'tailwind.config.js'
72
- template 'postcss.config.js', 'postcss.config.js'
73
74
  template 'vite.config.ts.tt', 'vite.config.ts'
74
75
  template 'Procfile.dev', 'Procfile.dev'
75
76
  template 'bin/watch', 'bin/watch'
@@ -34,6 +34,10 @@ class ApplicationController < ActionController::Base
34
34
 
35
35
  def set_layouts
36
36
  # "#{current_auth.user.role}/application"
37
- 'owner/application'
37
+ 'application'
38
38
  end
39
+
40
+ def ensure_turbo_frame!
41
+ turbo_frame_request? || turbo_native_app?
42
+ end
39
43
  end
@@ -5,7 +5,7 @@ import {stimulus} from "./stimulus"
5
5
  import WebController from "../pages/web"
6
6
  import SiteStimulusController from "../pages/stimulus.js"
7
7
 
8
- import "../stylesheets/application.scss"
8
+ import "../stylesheets/application.css"
9
9
  console.log("Kotaro is here")
10
10
  console.log(window.location.hash.slice(1))
11
11
 
@@ -1,116 +1,118 @@
1
- import {Controller} from "@hotwired/stimulus"
2
- import anime from "animejs";
1
+ import { Controller } from "@hotwired/stimulus"
3
2
 
4
3
  export default class extends Controller {
5
- confirmationDestroy(event) {
6
- const chooseTypes = document.querySelectorAll(".confirmation-destroy-" + event.params.id);
7
- chooseTypes.forEach((element) => {
8
- element.classList.remove('hidden');
9
- })
4
+ connect() {
5
+ this.sidebarEl = document.querySelector(".sidebar")
6
+ this.backdropEl = document.querySelector(".backdrop-active")
7
+ this.toggleBtns = document.querySelectorAll("[data-action~='web#sidebarToggle']")
8
+ if (!this.sidebarEl || !this.backdropEl) return
9
+
10
+ this.isOpen = false
11
+ this.prefersReduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches
12
+ this._onEsc = (e) => { if (e.key === "Escape") this.sidebarClose() }
13
+
14
+ this.backdropEl.addEventListener("click", () => this.sidebarClose(), { passive: true })
15
+
16
+ // Inisialisasi: pastikan posisi tertutup
17
+ this.sidebarEl.classList.add("-translate-x-full")
18
+ this.sidebarEl.classList.remove("translate-x-0")
19
+ this._setBackdrop(false)
10
20
  }
11
21
 
12
- confirmationDestroyCancel(event) {
13
- const chooseTypes = document.querySelectorAll(".confirmation-destroy-" + event.params.id);
14
- chooseTypes.forEach((element) => {
15
- element.classList.add('hidden');
16
- })
22
+ // === Sidebar ===
23
+ sidebarToggle(e) {
24
+ e?.preventDefault()
25
+ this.isOpen ? this.sidebarClose() : this.sidebarOpen(e?.currentTarget)
17
26
  }
18
27
 
19
- profileSetting(event) {
20
- console.log('Profile');
21
- const profileSettingBrowser = document.querySelector(".profile-browser");
22
- const profileSettingMobile = document.querySelector(".profile-mobile");
23
- if (profileSettingBrowser.classList.contains('hidden')) {
24
- profileSettingBrowser.classList.remove('hidden');
25
- console.log('show');
26
- } else {
27
- console.log('hide');
28
- profileSettingBrowser.classList.add('hidden');
29
- }
30
- if (profileSettingMobile.classList.contains('hidden')) {
31
- profileSettingMobile.classList.remove('hidden');
32
- console.log('show');
33
- } else {
34
- console.log('hide');
35
- profileSettingMobile.classList.add('hidden');
36
- }
28
+ sidebarOpen(triggerEl) {
29
+ if (this.isOpen) return
30
+ this.isOpen = true
31
+
32
+ // Kurangi jank: pastikan element “on GPU”
33
+ this.sidebarEl.style.transform = "translate3d(-100%,0,0)"
34
+ // Force reflow → lalu transisi ke posisi buka pada frame berikut
35
+ requestAnimationFrame(() => {
36
+ this.sidebarEl.classList.remove("-translate-x-full")
37
+ this.sidebarEl.classList.add("translate-x-0")
38
+ this.sidebarEl.style.transform = "" // kembalikan, biar Tailwind kelas yang mengatur
39
+ })
40
+
41
+ this._setBackdrop(true)
42
+ document.documentElement.classList.add("overflow-hidden")
43
+ triggerEl?.setAttribute("aria-expanded", "true")
44
+ this.sidebarEl.setAttribute("aria-hidden", "false")
45
+ document.addEventListener("keydown", this._onEsc, { passive: true })
46
+
47
+ // Fokus pertama
48
+ this.sidebarEl.querySelector("a, button, input, [tabindex]")
49
+ ?.focus({ preventScroll: true })
37
50
  }
38
51
 
39
- sidebarToggle(event) {
40
- const backdropActive = document.querySelector(".backdrop-active");
41
- const sidebar = document.querySelector(".sidebar");
42
- if (sidebar.classList.contains('side_hide')) {
43
- sidebar.classList.remove('side_hide');
44
- backdropActive.classList.remove('hidden');
45
- anime({
46
- targets: ".backdrop-active",
47
- translateX: 0,
48
- opacity: [0, 0.8],
49
- easing: 'easeInOutSine',
50
- complete: function (anim) {
51
- console.log('Backdrop Active');
52
- }
53
- })
54
- anime({
55
- targets: '.sidebar',
56
- translateX: 300,
57
- duration: 1000,
58
- easing: 'easeInOutExpo',
59
- complete: function (anim) {
60
- console.log('Sidebar show!');
61
- }
62
- });
63
- } else {
64
- sidebar.classList.add('side_hide');
65
- anime({
66
- targets: '.sidebar',
67
- easing: 'easeInOutExpo',
68
- translateX: -300,
69
- duration: 1000,
70
- complete: function (anim) {
71
- console.log('Sidebar Close!');
72
- }
73
- });
74
- anime({
75
- targets: ".backdrop-active",
76
- translateX: 0,
77
- opacity: [0.8, 0],
78
- easing: 'easeInOutSine',
79
- complete: function (anim) {
80
- backdropActive.classList.add('hidden');
81
- }
82
- })
83
- }
52
+ sidebarClose() {
53
+ if (!this.isOpen) return
54
+ this.isOpen = false
55
+
56
+ // Transisi balik (geser keluar)
57
+ this.sidebarEl.classList.add("-translate-x-full")
58
+ this.sidebarEl.classList.remove("translate-x-0")
59
+
60
+ this._setBackdrop(false)
61
+ document.documentElement.classList.remove("overflow-hidden")
62
+ this.sidebarEl.setAttribute("aria-hidden", "true")
63
+ this.toggleBtns.forEach((btn) => btn.setAttribute("aria-expanded", "false"))
64
+ document.removeEventListener("keydown", this._onEsc)
65
+ this.toggleBtns[0]?.focus({ preventScroll: true })
84
66
  }
85
67
 
86
68
  onSidebarClick(event) {
87
- event.preventDefault()
88
- const url = event.target.href;
89
- const backdropActive = document.querySelector(".backdrop-active");
90
- const sidebar = document.querySelector(".sidebar");
91
- if (url !== undefined) {
92
- sidebar.classList.add('side_hide');
93
- anime({
94
- targets: '.sidebar',
95
- easing: 'easeInOutExpo',
96
- translateX: -300,
97
- duration: 1000,
98
- complete: function (anim) {
99
- console.log('Sidebar Close!');
100
- }
101
- });
102
- anime({
103
- targets: ".backdrop-active",
104
- translateX: 0,
105
- opacity: [0.6, 0],
106
- easing: 'easeInOutSine',
107
- complete: function (anim) {
108
- console.log('opacity');
109
- backdropActive.classList.add('hidden');
110
- Turbo.visit(url);
69
+ const a = event.target.closest("a, button[type='submit']")
70
+ if (!a) return
71
+ setTimeout(() => this.sidebarClose(), 0)
72
+ }
73
+
74
+ // === Util ===
75
+ _setBackdrop(show) {
76
+ // Jika user minta “reduce motion”, skip animasi
77
+ if (this.prefersReduced) {
78
+ this.backdropEl.classList.toggle("hidden", !show)
79
+ this.backdropEl.classList.toggle("pointer-events-none", !show)
80
+ this.backdropEl.style.opacity = show ? "1" : "0"
81
+ return
82
+ }
83
+
84
+ // Pastikan elemen ada di flow saat mulai animasi
85
+ this.backdropEl.classList.remove("hidden")
86
+ requestAnimationFrame(() => {
87
+ if (show) {
88
+ this.backdropEl.classList.remove("opacity-0", "pointer-events-none")
89
+ this.backdropEl.classList.add("opacity-100")
90
+ } else {
91
+ // Fade out, lalu sembunyikan setelah selesai
92
+ this.backdropEl.classList.remove("opacity-100")
93
+ this.backdropEl.classList.add("opacity-0", "pointer-events-none")
94
+ const onEnd = () => {
95
+ this.backdropEl.classList.add("hidden")
96
+ this.backdropEl.removeEventListener("transitionend", onEnd)
111
97
  }
112
- })
98
+ this.backdropEl.addEventListener("transitionend", onEnd)
99
+ }
100
+ })
101
+ }
102
+
103
+ // Opsional: submenu & profil tetap bisa dipakai dari versi sebelumnya
104
+ profileSetting(event) {
105
+ const container = event.currentTarget.closest("li")
106
+ const dropdown = container?.querySelector("[class^='profile-']")
107
+ if (!dropdown) return
108
+
109
+ dropdown.classList.toggle("hidden")
110
+ const closeOnOutside = (e) => {
111
+ if (!dropdown.contains(e.target) && !event.currentTarget.contains(e.target)) {
112
+ dropdown.classList.add("hidden")
113
+ window.removeEventListener("click", closeOnOutside, true)
114
+ }
113
115
  }
116
+ window.addEventListener("click", closeOnOutside, true)
114
117
  }
115
118
  }
116
-
@@ -0,0 +1,221 @@
1
+ @import "tailwindcss";
2
+
3
+ @plugin "@tailwindcss/forms";
4
+ @plugin "@tailwindcss/typography";
5
+ @plugin "@tailwindcss/aspect-ratio";
6
+
7
+ @source "../../../app/views/**/*.html.erb";
8
+ @source "../../../app/views/**/*.rb";
9
+ @source "../../../app/helpers/**/*.rb";
10
+ @source "./app/frontend/**/*.{js,ts,jsx,tsx,css,scss,ejs}";
11
+
12
+
13
+ /* Theme tokens: memetakan screens & font family */
14
+ @theme {
15
+ /* Breakpoints (sesuai config kamu) */
16
+ --breakpoint-sm: 640px;
17
+ --breakpoint-md: 768px;
18
+ --breakpoint-lg: 1024px;
19
+ --breakpoint-xl: 1280px;
20
+ --breakpoint-2xl: 1536px;
21
+
22
+ /* Font stack: Open Sans + fallback default Tailwind */
23
+ --font-sans: "Open Sans", ui-sans-serif, system-ui, sans-serif,
24
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
25
+ }
26
+
27
+
28
+ @layer base {
29
+ * {
30
+ box-sizing: border-box;
31
+ }
32
+
33
+ *:before,
34
+ *:after {
35
+ box-sizing: border-box;
36
+ }
37
+
38
+ html {
39
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
40
+ }
41
+
42
+ body {
43
+ font-family: "Open Sans", sans-serif;
44
+ font-size: 1.6rem;
45
+ line-height: 1.75;
46
+ font-weight: 300;
47
+ color: #303030;
48
+ letter-spacing: 0.045em;
49
+ background-color: #fbfbfb;
50
+ }
51
+
52
+ .tooltip {
53
+ position: relative;
54
+ }
55
+
56
+ strong {
57
+ font-weight: 500;
58
+ }
59
+
60
+ .tooltip::before {
61
+ content: "";
62
+ position: absolute;
63
+ top: -6px;
64
+ left: 50%;
65
+ transform: translateX(-50%);
66
+ border-width: 4px 6px 0 6px;
67
+ border-style: solid;
68
+ border-color: rgba(0, 0, 0, 0.7) transparent transparent transparent;
69
+ z-index: 99;
70
+ opacity: 0;
71
+ transition: .3s opacity;
72
+ }
73
+
74
+ [tooltip-position='left']::before {
75
+ left: 0%;
76
+ top: 50%;
77
+ margin-left: -12px;
78
+ transform: translatey(-50%) rotate(-90deg)
79
+ }
80
+
81
+ [tooltip-position='top']::before {
82
+ left: 50%;
83
+ }
84
+
85
+ [tooltip-position='buttom']::before {
86
+ top: 100%;
87
+ margin-top: 8px;
88
+ transform: translateX(-50%) translatey(-100%) rotate(-180deg)
89
+ }
90
+
91
+ [tooltip-position='right']::before {
92
+ left: 100%;
93
+ top: 50%;
94
+ margin-left: 1px;
95
+ transform: translatey(-50%) rotate(90deg)
96
+ }
97
+
98
+ .tooltip::after {
99
+ content: attr(data-text);
100
+ position: absolute;
101
+ min-width: 10rem;
102
+ left: 50%;
103
+ top: -6px;
104
+ transform: translateX(-50%) translateY(-100%);
105
+ background: rgba(0, 0, 0, 0.7);
106
+ text-align: center;
107
+ color: #fff;
108
+ font-size: 12px;
109
+ border-radius: 5px;
110
+ pointer-events: none;
111
+ padding: 4px 4px;
112
+ z-index: 99;
113
+ opacity: 0;
114
+ transition: .3s opacity;
115
+ }
116
+
117
+ [tooltip-position='left']::after {
118
+ left: 0;
119
+ top: 50%;
120
+ margin-left: -8px;
121
+ transform: translateX(-100%) translateY(-50%);
122
+ }
123
+
124
+ [tooltip-position='top']::after {
125
+ left: 50%;
126
+ }
127
+
128
+ [tooltip-position='buttom']::after {
129
+ top: 100%;
130
+ margin-top: 8px;
131
+ transform: translateX(-50%) translateY(0%);
132
+ }
133
+
134
+ [tooltip-position='right']::after {
135
+ left: 100%;
136
+ top: 50%;
137
+ margin-left: 8px;
138
+ transform: translateX(0%) translateY(-50%);
139
+ }
140
+
141
+ .tooltip:hover::after, .tooltip:hover::before {
142
+ opacity: 1
143
+ }
144
+
145
+
146
+ pre {
147
+ white-space: pre-wrap;
148
+ word-wrap: break-word;
149
+ }
150
+
151
+ //#------------
152
+ h1 {
153
+ @apply text-2xl;
154
+ }
155
+
156
+ h2 {
157
+ @apply text-xl;
158
+ }
159
+
160
+ h3 {
161
+ @apply text-lg;
162
+ }
163
+
164
+ .class-button {
165
+ @apply rounded-md px-3 py-2 text-center text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2;
166
+ @apply focus-visible:outline-gray-500 bg-gray-500 hover:bg-white hover:text-gray-500 hover:border-gray-50 hover:outline;
167
+ }
168
+
169
+ .class-button-outline {
170
+ @apply rounded-md px-3 py-2 text-center text-sm font-semibold text-gray-500 shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2;
171
+ @apply outline outline-1 border-gray-500 focus-visible:outline-gray-500 bg-white hover:bg-gray-500 hover:text-white hover:border-gray-500 hover:outline;
172
+ }
173
+
174
+ .class-label {
175
+ @apply text-sm font-semibold leading-6 text-gray-900;
176
+ }
177
+
178
+ .class-text-field {
179
+ @apply block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6;
180
+ }
181
+
182
+ .class-card-container {
183
+ @apply overflow-hidden bg-white shadow sm:rounded-lg p-5
184
+ }
185
+
186
+ .class-input {
187
+ @apply sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 sm:py-6 pl-2
188
+ }
189
+
190
+ .class-tr {
191
+ @apply top-0 z-10 border-b border-gray-300 bg-white/75 px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell
192
+ }
193
+
194
+ .class-td {
195
+ @apply whitespace-nowrap px-3 py-5 text-sm text-gray-500
196
+ }
197
+
198
+ .class-menu-link {
199
+ @apply hover:font-semibold hover:text-gray-500 block rounded-md py-2 pr-2 pl-9 text-sm leading-6 text-gray-700
200
+ }
201
+
202
+ .class-text-link {
203
+ @apply hover:font-semibold hover:text-gray-500 block rounded-md text-sm leading-6 text-gray-700
204
+ }
205
+
206
+ .class-menu-active-link {
207
+ @apply font-semibold block rounded-md py-2 pr-2 pl-9 text-sm leading-6 text-gray-700
208
+ }
209
+ }
210
+
211
+ @layer utilities {
212
+ /* Chrome, Safari and Opera */
213
+ .no-scrollbar::-webkit-scrollbar {
214
+ display: none;
215
+ }
216
+
217
+ .no-scrollbar {
218
+ -ms-overflow-style: none; /* IE and Edge */
219
+ scrollbar-width: none; /* Firefox */
220
+ }
221
+ }
@@ -5,7 +5,7 @@
5
5
  </svg>
6
6
  </button>
7
7
  <div class="confirmation-destroy-<%%= value.id %> hidden relative z-10" aria-labelledby="modal-title" role="dialog" aria-modal="false">
8
- <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity min-h-screen z-100"></div>
8
+ <div class="fixed inset-0 bg-gray-500/75 transition-opacity min-h-screen z-100"></div>
9
9
  <div class="fixed inset-0 z-100 w-screen overflow-y-auto">
10
10
  <div class="flex min-h-full justify-center p-4 text-center items-center sm:p-0">
11
11
  <div class="relative transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg sm:p-6">
@@ -16,8 +16,7 @@
16
16
  <%%= csp_meta_tag %>
17
17
 
18
18
  <%%= vite_client_tag %>
19
- <%%= vite_stylesheet_tag 'application.scss', data: { "turbo-track": "reload" } %>
20
- <%%= vite_javascript_tag 'application' %>
19
+ <%%= vite_javascript_tag "application", "data-turbo-track": "reload", defer: true %>
21
20
  </head>
22
21
 
23
22
  <body class="h-full" data-turbo="true">
@@ -16,7 +16,7 @@
16
16
  <%%= csp_meta_tag %>
17
17
 
18
18
  <%%= vite_client_tag %>
19
- <%%= vite_javascript_tag 'application', data: { "turbo-track": "reload" } %>
19
+ <%%= vite_javascript_tag "application", "data-turbo-track": "reload", defer: true %>
20
20
  </head>
21
21
 
22
22
  <body class="h-full" data-turbo="true">
@@ -27,7 +27,11 @@
27
27
  <div class="relative isolate flex min-h-svh w-full bg-white max-lg:flex-col lg:bg-zinc-100 dark:bg-zinc-900 dark:lg:bg-zinc-950">
28
28
 
29
29
  <%%# mobile %>
30
- <div class="fixed bg-white rounded-2xl m-2 inset-y-0 w-64 -left-[300px] lg:hidden sidebar side_hide z-50" data-action="click->web#onSidebarClick">
30
+ <div
31
+ class="fixed inset-y-0 left-0 z-50 w-64 max-w-[85vw] bg-white rounded-2xl m-2
32
+ -translate-x-full will-change-transform transition-transform duration-300 ease-out
33
+ lg:hidden sidebar"
34
+ data-action="click->web#onSidebarClick">
31
35
  <nav class="flex h-full min-h-0 flex-col">
32
36
  <%%= render "components/layouts/sidebar", from: :mobile %>
33
37
  </nav>
@@ -53,7 +57,10 @@
53
57
  </div>
54
58
 
55
59
  <main class="flex flex-1 flex-col pb-2 lg:min-w-0 lg:pl-64 lg:pr-2 lg:pt-2">
56
- <div class="fixed inset-0 bg-gray-900 backdrop-blur-lg backdrop-active opacity-0 hidden lg:hidden" aria-hidden="true"></div>
60
+ <div
61
+ class="fixed inset-0 z-40 bg-black/50 opacity-0 pointer-events-none
62
+ transition-opacity duration-300 ease-out backdrop-active lg:hidden hidden"
63
+ aria-hidden="true"></div>
57
64
  <div class="grow p-6 lg:rounded-lg lg:bg-white lg:p-10 lg:shadow-sm lg:ring-1 lg:ring-zinc-950/5 dark:lg:bg-zinc-900 dark:lg:ring-white/10">
58
65
  <div class="mx-auto max-w-6xl">
59
66
  <%%= yield %>
@@ -2,9 +2,12 @@ import {defineConfig} from 'vite'
2
2
  import RubyPlugin from 'vite-plugin-ruby'
3
3
  import FullReload from 'vite-plugin-full-reload'
4
4
  import StimulusHMR from 'vite-plugin-stimulus-hmr';
5
+ // @ts-ignore
6
+ import tailwindcss from "@tailwindcss/vite";
5
7
  export default defineConfig({
6
8
  plugins: [
7
9
  RubyPlugin(),
10
+ tailwindcss(),
8
11
  FullReload(['config/routes.rb', 'app/views/**/*', 'app/frontend/pages/**/*']),
9
12
  StimulusHMR()
10
13
  ],
@@ -16,12 +19,5 @@ export default defineConfig({
16
19
  application: 'app/frontend/entrypoints/application.js'
17
20
  }
18
21
  }
19
- },
20
- css: {
21
- preprocessorOptions: {
22
- scss: {
23
- api: 'modern-compiler' // or "modern"
24
- }
25
- }
26
22
  }
27
23
  })
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SunSword
4
- VERSION = '0.0.9'
4
+ VERSION = '0.0.10'
5
5
  public_constant :VERSION
6
6
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sun-sword
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - kotarominami
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-11-25 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
@@ -88,12 +87,10 @@ files:
88
87
  - lib/generators/sun_sword/templates_frontend/frontend/entrypoints/stimulus.js
89
88
  - lib/generators/sun_sword/templates_frontend/frontend/pages/stimulus.js
90
89
  - lib/generators/sun_sword/templates_frontend/frontend/pages/web.js
91
- - lib/generators/sun_sword/templates_frontend/frontend/stylesheets/application.scss
90
+ - lib/generators/sun_sword/templates_frontend/frontend/stylesheets/application.css
92
91
  - lib/generators/sun_sword/templates_frontend/helpers/application_helper.rb
93
92
  - lib/generators/sun_sword/templates_frontend/package.json
94
- - lib/generators/sun_sword/templates_frontend/postcss.config.js
95
93
  - lib/generators/sun_sword/templates_frontend/rubocop.yml.tt
96
- - lib/generators/sun_sword/templates_frontend/tailwind.config.js
97
94
  - lib/generators/sun_sword/templates_frontend/views/components/_action_destroy.html.erb.tt
98
95
  - lib/generators/sun_sword/templates_frontend/views/components/_action_edit.html.erb.tt
99
96
  - lib/generators/sun_sword/templates_frontend/views/components/_action_show.html.erb.tt
@@ -124,7 +121,6 @@ licenses:
124
121
  - MIT
125
122
  metadata:
126
123
  source_code_uri: https://github.com/kotaroisme/sun-sword
127
- post_install_message:
128
124
  rdoc_options: []
129
125
  require_paths:
130
126
  - lib
@@ -139,8 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
135
  - !ruby/object:Gem::Version
140
136
  version: '0'
141
137
  requirements: []
142
- rubygems_version: 3.5.23
143
- signing_key:
138
+ rubygems_version: 3.7.2
144
139
  specification_version: 4
145
140
  summary: Sun Sword is a Generator for Clean Architecture
146
141
  test_files: []
@@ -1,198 +0,0 @@
1
- @use "tailwindcss/base";
2
- @use "tailwindcss/components";
3
- @use "tailwindcss/utilities";
4
-
5
- @layer base {
6
- * {
7
- box-sizing: border-box;
8
- }
9
-
10
- *:before,
11
- *:after {
12
- box-sizing: border-box;
13
- }
14
-
15
- html {
16
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
17
- }
18
-
19
- body {
20
- font-family: "Open Sans", sans-serif;
21
- font-size: 1.6rem;
22
- line-height: 1.75;
23
- font-weight: 300;
24
- color: #303030;
25
- letter-spacing: 0.045em;
26
- background-color: #fbfbfb;
27
- }
28
-
29
- .tooltip {
30
- position: relative;
31
- }
32
-
33
- strong {
34
- font-weight: 500;
35
- }
36
-
37
- .tooltip::before {
38
- content: "";
39
- position: absolute;
40
- top: -6px;
41
- left: 50%;
42
- transform: translateX(-50%);
43
- border-width: 4px 6px 0 6px;
44
- border-style: solid;
45
- border-color: rgba(0, 0, 0, 0.7) transparent transparent transparent;
46
- z-index: 99;
47
- opacity: 0;
48
- transition: .3s opacity;
49
- }
50
-
51
- [tooltip-position='left']::before {
52
- left: 0%;
53
- top: 50%;
54
- margin-left: -12px;
55
- transform: translatey(-50%) rotate(-90deg)
56
- }
57
-
58
- [tooltip-position='top']::before {
59
- left: 50%;
60
- }
61
-
62
- [tooltip-position='buttom']::before {
63
- top: 100%;
64
- margin-top: 8px;
65
- transform: translateX(-50%) translatey(-100%) rotate(-180deg)
66
- }
67
-
68
- [tooltip-position='right']::before {
69
- left: 100%;
70
- top: 50%;
71
- margin-left: 1px;
72
- transform: translatey(-50%) rotate(90deg)
73
- }
74
-
75
- .tooltip::after {
76
- content: attr(data-text);
77
- position: absolute;
78
- min-width: 10rem;
79
- left: 50%;
80
- top: -6px;
81
- transform: translateX(-50%) translateY(-100%);
82
- background: rgba(0, 0, 0, 0.7);
83
- text-align: center;
84
- color: #fff;
85
- font-size: 12px;
86
- border-radius: 5px;
87
- pointer-events: none;
88
- padding: 4px 4px;
89
- z-index: 99;
90
- opacity: 0;
91
- transition: .3s opacity;
92
- }
93
-
94
- [tooltip-position='left']::after {
95
- left: 0;
96
- top: 50%;
97
- margin-left: -8px;
98
- transform: translateX(-100%) translateY(-50%);
99
- }
100
-
101
- [tooltip-position='top']::after {
102
- left: 50%;
103
- }
104
-
105
- [tooltip-position='buttom']::after {
106
- top: 100%;
107
- margin-top: 8px;
108
- transform: translateX(-50%) translateY(0%);
109
- }
110
-
111
- [tooltip-position='right']::after {
112
- left: 100%;
113
- top: 50%;
114
- margin-left: 8px;
115
- transform: translateX(0%) translateY(-50%);
116
- }
117
-
118
- .tooltip:hover::after, .tooltip:hover::before {
119
- opacity: 1
120
- }
121
-
122
-
123
- pre {
124
- white-space: pre-wrap;
125
- word-wrap: break-word;
126
- }
127
-
128
- //#------------
129
- h1 {
130
- @apply text-2xl;
131
- }
132
-
133
- h2 {
134
- @apply text-xl;
135
- }
136
-
137
- h3 {
138
- @apply text-lg;
139
- }
140
-
141
- .class-button {
142
- @apply rounded-md px-3 py-2 text-center text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2;
143
- @apply focus-visible:outline-gray-500 bg-gray-500 hover:bg-white hover:text-gray-500 hover:border-gray-50 hover:outline;
144
- }
145
-
146
- .class-button-outline {
147
- @apply rounded-md px-3 py-2 text-center text-sm font-semibold text-gray-500 shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2;
148
- @apply outline outline-1 border-gray-500 focus-visible:outline-gray-500 bg-white hover:bg-gray-500 hover:text-white hover:border-gray-500 hover:outline;
149
- }
150
-
151
- .class-label {
152
- @apply text-sm font-semibold leading-6 text-gray-900;
153
- }
154
-
155
- .class-text-field {
156
- @apply block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6;
157
- }
158
-
159
- .class-card-container {
160
- @apply overflow-hidden bg-white shadow sm:rounded-lg p-5
161
- }
162
-
163
- .class-input {
164
- @apply sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 sm:py-6 pl-2
165
- }
166
-
167
- .class-tr {
168
- @apply top-0 z-10 border-b border-gray-300 bg-white bg-opacity-75 px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell
169
- }
170
-
171
- .class-td {
172
- @apply whitespace-nowrap px-3 py-5 text-sm text-gray-500
173
- }
174
-
175
- .class-menu-link {
176
- @apply hover:font-semibold hover:text-gray-500 block rounded-md py-2 pr-2 pl-9 text-sm leading-6 text-gray-700
177
- }
178
-
179
- .class-text-link {
180
- @apply hover:font-semibold hover:text-gray-500 block rounded-md text-sm leading-6 text-gray-700
181
- }
182
-
183
- .class-menu-active-link {
184
- @apply font-semibold block rounded-md py-2 pr-2 pl-9 text-sm leading-6 text-gray-700
185
- }
186
- }
187
-
188
- @layer utilities {
189
- /* Chrome, Safari and Opera */
190
- .no-scrollbar::-webkit-scrollbar {
191
- display: none;
192
- }
193
-
194
- .no-scrollbar {
195
- -ms-overflow-style: none; /* IE and Edge */
196
- scrollbar-width: none; /* Firefox */
197
- }
198
- }
@@ -1,6 +0,0 @@
1
- export default {
2
- plugins: {
3
- tailwindcss: {},
4
- autoprefixer: {},
5
- },
6
- }
@@ -1,39 +0,0 @@
1
- /** @type {import('tailwindcss').Config} */
2
- const defaultTheme = require('tailwindcss/defaultTheme')
3
-
4
- module.exports = {
5
- content: [
6
- './app/helpers/**/*.rb',
7
- './app/views/**/*.{.erb,erb}',
8
- './app/frontend/**/*.{js, css, scss, ejs}',
9
- ],
10
- theme: {
11
- screens: {
12
- 'sm': '640px',
13
- // => @media (min-width: 640px) { ... }
14
-
15
- 'md': '768px',
16
- // => @media (min-width: 768px) { ... }
17
-
18
- 'lg': '1024px',
19
- // => @media (min-width: 1024px) { ... }
20
-
21
- 'xl': '1280px',
22
- // => @media (min-width: 1280px) { ... }
23
-
24
- '2xl': '1536px',
25
- // => @media (min-width: 1536px) { ... }
26
- },
27
- extend: {
28
- fontFamily: {
29
- sans: ['Open Sans', ...defaultTheme.fontFamily.sans],
30
- },
31
- },
32
- },
33
- plugins: [
34
- require('@tailwindcss/aspect-ratio'),
35
- require('@tailwindcss/forms'),
36
- require('@tailwindcss/typography'),
37
- ],
38
- }
39
-