senren-ui 0.3.0 → 0.4.1
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 +4 -4
- data/CHANGELOG.md +147 -0
- data/CONTRIBUTING.md +10 -0
- data/README.md +36 -0
- data/docs/i18n.md +194 -0
- data/lib/commands/senren/add/add_command.rb +4 -1
- data/lib/commands/senren/locales/locales_command.rb +38 -0
- data/lib/generators/senren/install/install_generator.rb +36 -0
- data/lib/generators/senren/install/templates/base_component.rb.tt +39 -0
- data/lib/generators/senren/install/templates/conventions.md.tt +16 -0
- data/lib/generators/senren/install/templates/installed_components.yml.tt +1 -1
- data/lib/senren/rails/agent_rules_writer.rb +4 -0
- data/lib/senren/rails/base_component_patch.rb +24 -0
- data/lib/senren/rails/component_copier.rb +21 -0
- data/lib/senren/rails/doctor.rb +5 -1
- data/lib/senren/rails/host_paths.rb +5 -0
- data/lib/senren/rails/locale_installer.rb +90 -0
- data/lib/senren/rails/version.rb +1 -1
- data/lib/senren/rails.rb +1 -0
- data/lib/tasks/senren.rake +9 -0
- data/templates/components/accordion/accordion_component.html.erb +22 -4
- data/templates/components/accordion/accordion_component.rb +2 -1
- data/templates/components/alert_dialog/alert_dialog_component.html.erb +1 -1
- data/templates/components/api_key_field/api_key_field_component.html.erb +1 -1
- data/templates/components/api_key_field/api_key_field_component.rb +8 -1
- data/templates/components/app_shell/app_shell_component.rb +2 -1
- data/templates/components/breadcrumb/breadcrumb_component.rb +2 -1
- data/templates/components/bulk_action_bar/bulk_action_bar_component.html.erb +1 -1
- data/templates/components/bulk_action_bar/bulk_action_bar_component.rb +4 -2
- data/templates/components/calendar/calendar_component.rb +37 -2
- data/templates/components/carousel/carousel_component.html.erb +5 -5
- data/templates/components/carousel/carousel_component.rb +12 -1
- data/templates/components/cart/cart_component.html.erb +6 -6
- data/templates/components/cart/cart_component.rb +11 -2
- data/templates/components/clipboard/clipboard_component.html.erb +1 -1
- data/templates/components/clipboard/clipboard_component.rb +6 -1
- data/templates/components/collapsible/collapsible_component.rb +1 -1
- data/templates/components/combobox/combobox_component.rb +2 -1
- data/templates/components/command/command_component.rb +3 -1
- data/templates/components/data_table/data_table_component.html.erb +3 -3
- data/templates/components/data_table/data_table_component.rb +16 -1
- data/templates/components/date_picker/date_picker_component.html.erb +2 -2
- data/templates/components/date_picker/date_picker_component.rb +2 -1
- data/templates/components/dialog/dialog_component.html.erb +2 -2
- data/templates/components/filter_bar/filter_bar_component.rb +1 -1
- data/templates/components/form/form_component.html.erb +1 -1
- data/templates/components/form/form_component.rb +21 -0
- data/templates/components/invite_member_dialog/invite_member_dialog_component.html.erb +9 -8
- data/templates/components/invite_member_dialog/invite_member_dialog_component.rb +11 -3
- data/templates/components/native_select/native_select_component.rb +12 -3
- data/templates/components/pagination/pagination_component.html.erb +2 -2
- data/templates/components/pagination/pagination_component.rb +2 -1
- data/templates/components/product_card/product_card_component.html.erb +1 -1
- data/templates/components/product_card/product_card_component.rb +2 -2
- data/templates/components/rich_text_editor_lite/rich_text_editor_lite_component.html.erb +2 -16
- data/templates/components/rich_text_editor_lite/rich_text_editor_lite_component.rb +32 -1
- data/templates/components/search_input/search_input_component.rb +2 -1
- data/templates/components/sheet/sheet_component.html.erb +2 -2
- data/templates/components/sidebar/sidebar_component.html.erb +2 -2
- data/templates/components/sidebar/sidebar_component.rb +4 -1
- data/templates/components/table/table_component.html.erb +1 -1
- data/templates/components/tabs/tabs_component.rb +4 -2
- data/templates/components/theme_toggle/theme_toggle_component.html.erb +17 -3
- data/templates/components/theme_toggle/theme_toggle_component.rb +6 -1
- data/templates/components/top_nav/top_nav_component.html.erb +1 -1
- data/templates/components/top_nav/top_nav_component.rb +3 -2
- data/templates/controllers/accordion_controller.js +68 -3
- data/templates/controllers/api_key_field_controller.js +3 -2
- data/templates/controllers/carousel_controller.js +6 -1
- data/templates/controllers/clipboard_controller.js +3 -3
- data/templates/controllers/rich_text_editor_lite_controller.js +2 -2
- data/templates/controllers/theme_toggle_controller.js +13 -3
- data/templates/locales/senren.en.yml +151 -0
- data/templates/locales/senren.vi.yml +151 -0
- metadata +6 -1
|
@@ -6,7 +6,8 @@ export default class extends Controller {
|
|
|
6
6
|
static values = {
|
|
7
7
|
revealLabel: String,
|
|
8
8
|
hideLabel: String,
|
|
9
|
-
copyLabel: String
|
|
9
|
+
copyLabel: String,
|
|
10
|
+
copiedStatus: String
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
connect() {
|
|
@@ -31,6 +32,6 @@ export default class extends Controller {
|
|
|
31
32
|
this.inputTarget.setSelectionRange(0, 0)
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
if (this.hasStatusTarget) this.statusTarget.textContent =
|
|
35
|
+
if (this.hasStatusTarget) this.statusTarget.textContent = this.copiedStatusValue
|
|
35
36
|
}
|
|
36
37
|
}
|
|
@@ -4,6 +4,7 @@ import { Controller } from "@hotwired/stimulus"
|
|
|
4
4
|
// Local UI: previous/next controls, dots, and arrow-key navigation.
|
|
5
5
|
export default class extends Controller {
|
|
6
6
|
static targets = ["slide", "dot", "status"]
|
|
7
|
+
static values = { statusTemplate: String }
|
|
7
8
|
|
|
8
9
|
connect() {
|
|
9
10
|
this.index = 0
|
|
@@ -45,6 +46,10 @@ export default class extends Controller {
|
|
|
45
46
|
this.dotTargets.forEach((dot, dotIndex) => {
|
|
46
47
|
dot.setAttribute("aria-current", dotIndex === this.index ? "true" : "false")
|
|
47
48
|
})
|
|
48
|
-
if (this.hasStatusTarget
|
|
49
|
+
if (this.hasStatusTarget && this.statusTemplateValue) {
|
|
50
|
+
this.statusTarget.textContent = this.statusTemplateValue
|
|
51
|
+
.replaceAll("%{current}", this.index + 1)
|
|
52
|
+
.replaceAll("%{total}", count)
|
|
53
|
+
}
|
|
49
54
|
}
|
|
50
55
|
}
|
|
@@ -4,7 +4,7 @@ import { Controller } from "@hotwired/stimulus"
|
|
|
4
4
|
// Local UI: copy text to the clipboard and announce success.
|
|
5
5
|
export default class extends Controller {
|
|
6
6
|
static targets = ["source", "button", "status"]
|
|
7
|
-
static values = { copiedLabel: String }
|
|
7
|
+
static values = { copiedLabel: String, copiedStatus: String }
|
|
8
8
|
|
|
9
9
|
async copy() {
|
|
10
10
|
const value = this.sourceTarget.value || this.sourceTarget.textContent
|
|
@@ -13,8 +13,8 @@ export default class extends Controller {
|
|
|
13
13
|
if (!this.hasButtonTarget) return
|
|
14
14
|
|
|
15
15
|
const original = this.buttonTarget.textContent
|
|
16
|
-
this.buttonTarget.textContent = this.copiedLabelValue
|
|
17
|
-
if (this.hasStatusTarget) this.statusTarget.textContent =
|
|
16
|
+
if (this.copiedLabelValue) this.buttonTarget.textContent = this.copiedLabelValue
|
|
17
|
+
if (this.hasStatusTarget) this.statusTarget.textContent = this.copiedStatusValue
|
|
18
18
|
|
|
19
19
|
clearTimeout(this._resetTimer)
|
|
20
20
|
this._resetTimer = setTimeout(() => {
|
|
@@ -16,7 +16,7 @@ const DROPPED_PASTE_TAGS = new Set(["SCRIPT", "STYLE", "NOSCRIPT", "TEMPLATE", "
|
|
|
16
16
|
// Local UI: tiny contenteditable toolbar synced to a hidden textarea.
|
|
17
17
|
export default class extends Controller {
|
|
18
18
|
static targets = ["editor", "input", "button"]
|
|
19
|
-
static values = { debug: Boolean }
|
|
19
|
+
static values = { debug: Boolean, linkPrompt: String }
|
|
20
20
|
|
|
21
21
|
connect() {
|
|
22
22
|
this.savedRange = null
|
|
@@ -59,7 +59,7 @@ export default class extends Controller {
|
|
|
59
59
|
this.debug("format:start", () => ({ command, before: this.snapshot() }))
|
|
60
60
|
this.restoreSelection()
|
|
61
61
|
if (command === "createLink") {
|
|
62
|
-
const url = window.prompt(
|
|
62
|
+
const url = window.prompt(this.linkPromptValue)
|
|
63
63
|
this.debug("createLink:prompt", () => ({ url, afterPrompt: this.snapshot() }))
|
|
64
64
|
if (!url) return
|
|
65
65
|
this.restoreSelection()
|
|
@@ -3,7 +3,8 @@ import { Controller } from "@hotwired/stimulus"
|
|
|
3
3
|
// senren--theme-toggle
|
|
4
4
|
// Local UI: toggles the document dark class and stores the preference.
|
|
5
5
|
export default class extends Controller {
|
|
6
|
-
static targets = ["label", "
|
|
6
|
+
static targets = ["label", "iconLight", "iconDark"]
|
|
7
|
+
static values = { lightLabel: String, darkLabel: String }
|
|
7
8
|
|
|
8
9
|
connect() {
|
|
9
10
|
this._sync()
|
|
@@ -18,7 +19,16 @@ export default class extends Controller {
|
|
|
18
19
|
_sync() {
|
|
19
20
|
const dark = document.documentElement.classList.contains("dark")
|
|
20
21
|
this.element.setAttribute("aria-pressed", dark ? "true" : "false")
|
|
21
|
-
if (this.hasLabelTarget) this.labelTarget.textContent = dark ?
|
|
22
|
-
|
|
22
|
+
if (this.hasLabelTarget) this.labelTarget.textContent = dark ? this.lightLabelValue : this.darkLabelValue
|
|
23
|
+
|
|
24
|
+
// The icon names the theme the click switches *to*, matching the label: in
|
|
25
|
+
// light mode the label reads "Dark theme", so the moon is showing. Showing
|
|
26
|
+
// the current state instead would have icon and label contradict each other.
|
|
27
|
+
//
|
|
28
|
+
// Swapping visibility rather than rewriting one element's text also means
|
|
29
|
+
// the icons are markup the server rendered, so the right one is on screen
|
|
30
|
+
// before this controller connects.
|
|
31
|
+
if (this.hasIconLightTarget) this.iconLightTarget.hidden = !dark
|
|
32
|
+
if (this.hasIconDarkTarget) this.iconDarkTarget.hidden = dark
|
|
23
33
|
}
|
|
24
34
|
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Senren UI - English strings. This is the canonical wording.
|
|
2
|
+
#
|
|
3
|
+
# GENERATED by bin/i18n-sync from the senren_t(key, default:) calls in
|
|
4
|
+
# templates/components. Do not edit it by hand: change the `default:` in the
|
|
5
|
+
# component and run bin/i18n-sync, or a test will fail.
|
|
6
|
+
#
|
|
7
|
+
# Copy this file to senren.<locale>.yml, change the top-level `en:` to your
|
|
8
|
+
# locale, and translate the values. Keep every %{variable} - they are filled in
|
|
9
|
+
# when the component renders. A key you leave out falls back to the English.
|
|
10
|
+
en:
|
|
11
|
+
senren:
|
|
12
|
+
shared:
|
|
13
|
+
open: "Open"
|
|
14
|
+
close: "Close"
|
|
15
|
+
accordion:
|
|
16
|
+
section: "Section %{number}"
|
|
17
|
+
api_key_field:
|
|
18
|
+
label: "API key"
|
|
19
|
+
reveal: "Reveal"
|
|
20
|
+
hide: "Hide"
|
|
21
|
+
copy: "Copy"
|
|
22
|
+
copied_status: "%{label} complete"
|
|
23
|
+
app_shell:
|
|
24
|
+
skip_to_content: "Skip to content"
|
|
25
|
+
breadcrumb:
|
|
26
|
+
label: "Breadcrumb"
|
|
27
|
+
bulk_action_bar:
|
|
28
|
+
items: "items"
|
|
29
|
+
selected: "%{count} %{item_label} selected"
|
|
30
|
+
ready: "Selection ready"
|
|
31
|
+
calendar:
|
|
32
|
+
title: "%{month} %{year}"
|
|
33
|
+
months:
|
|
34
|
+
january: "January"
|
|
35
|
+
february: "February"
|
|
36
|
+
march: "March"
|
|
37
|
+
april: "April"
|
|
38
|
+
may: "May"
|
|
39
|
+
june: "June"
|
|
40
|
+
july: "July"
|
|
41
|
+
august: "August"
|
|
42
|
+
september: "September"
|
|
43
|
+
october: "October"
|
|
44
|
+
november: "November"
|
|
45
|
+
december: "December"
|
|
46
|
+
weekdays:
|
|
47
|
+
sun: "Sun"
|
|
48
|
+
mon: "Mon"
|
|
49
|
+
tue: "Tue"
|
|
50
|
+
wed: "Wed"
|
|
51
|
+
thu: "Thu"
|
|
52
|
+
fri: "Fri"
|
|
53
|
+
sat: "Sat"
|
|
54
|
+
carousel:
|
|
55
|
+
label: "Carousel"
|
|
56
|
+
previous: "Previous slide"
|
|
57
|
+
next: "Next slide"
|
|
58
|
+
go_to: "Go to slide %{number}"
|
|
59
|
+
status: "Slide %{current} of %{total}"
|
|
60
|
+
cart:
|
|
61
|
+
title: "Cart"
|
|
62
|
+
empty: "Your cart is empty."
|
|
63
|
+
checkout: "Checkout"
|
|
64
|
+
subtotal: "Subtotal"
|
|
65
|
+
remove: "Remove"
|
|
66
|
+
quantity_group: "%{name} quantity"
|
|
67
|
+
decrease: "Decrease %{name} quantity"
|
|
68
|
+
increase: "Increase %{name} quantity"
|
|
69
|
+
remove_item: "Remove %{name}"
|
|
70
|
+
clipboard:
|
|
71
|
+
copy: "Copy"
|
|
72
|
+
copied: "Copied"
|
|
73
|
+
copied_status: "Copied to clipboard"
|
|
74
|
+
collapsible:
|
|
75
|
+
details: "Details"
|
|
76
|
+
combobox:
|
|
77
|
+
placeholder: "Search..."
|
|
78
|
+
command:
|
|
79
|
+
placeholder: "Type a command..."
|
|
80
|
+
label: "Command menu"
|
|
81
|
+
empty: "No results found."
|
|
82
|
+
data_table:
|
|
83
|
+
empty: "No records found."
|
|
84
|
+
sort: "Sort"
|
|
85
|
+
date_picker:
|
|
86
|
+
placeholder: "Select date"
|
|
87
|
+
today: "Today"
|
|
88
|
+
clear: "Clear"
|
|
89
|
+
filter_bar:
|
|
90
|
+
label: "Filters"
|
|
91
|
+
invite_member_dialog:
|
|
92
|
+
title: "Invite teammate"
|
|
93
|
+
description: "Send an invitation to join this workspace."
|
|
94
|
+
role_member: "Member"
|
|
95
|
+
role_admin: "Admin"
|
|
96
|
+
button: "Invite member"
|
|
97
|
+
email: "Email"
|
|
98
|
+
email_placeholder: "teammate@company.com"
|
|
99
|
+
role: "Role"
|
|
100
|
+
cancel: "Cancel"
|
|
101
|
+
send: "Send invite"
|
|
102
|
+
pagination:
|
|
103
|
+
label: "Pagination"
|
|
104
|
+
previous: "Previous"
|
|
105
|
+
next: "Next"
|
|
106
|
+
product_card:
|
|
107
|
+
add_to_cart: "Add to cart"
|
|
108
|
+
out_of_stock: "Out of stock"
|
|
109
|
+
no_image: "No image"
|
|
110
|
+
rich_text_editor_lite:
|
|
111
|
+
label: "Content"
|
|
112
|
+
placeholder: "Write something..."
|
|
113
|
+
link_prompt: "Paste a URL"
|
|
114
|
+
toolbar:
|
|
115
|
+
paragraph: "Paragraph"
|
|
116
|
+
heading_1: "Heading 1"
|
|
117
|
+
heading_2: "Heading 2"
|
|
118
|
+
heading_3: "Heading 3"
|
|
119
|
+
bold: "Bold"
|
|
120
|
+
italic: "Italic"
|
|
121
|
+
create_link: "Create link"
|
|
122
|
+
bulleted_list: "Bulleted list"
|
|
123
|
+
numbered_list: "Numbered list"
|
|
124
|
+
align_left: "Align left"
|
|
125
|
+
align_center: "Align center"
|
|
126
|
+
align_right: "Align right"
|
|
127
|
+
justify: "Justify"
|
|
128
|
+
toolbar_short:
|
|
129
|
+
link: "Link"
|
|
130
|
+
list: "List"
|
|
131
|
+
left: "Left"
|
|
132
|
+
center: "Center"
|
|
133
|
+
right: "Right"
|
|
134
|
+
justify: "Justify"
|
|
135
|
+
search_input:
|
|
136
|
+
placeholder: "Search..."
|
|
137
|
+
label: "Search"
|
|
138
|
+
sidebar:
|
|
139
|
+
brand: "Senren"
|
|
140
|
+
label: "Primary"
|
|
141
|
+
toggle: "Toggle sidebar"
|
|
142
|
+
tabs:
|
|
143
|
+
label: "Tabs"
|
|
144
|
+
tab: "Tab %{number}"
|
|
145
|
+
theme_toggle:
|
|
146
|
+
label: "Toggle theme"
|
|
147
|
+
light: "Light theme"
|
|
148
|
+
dark: "Dark theme"
|
|
149
|
+
top_nav:
|
|
150
|
+
label: "Global"
|
|
151
|
+
brand: "Senren"
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Senren UI - Vietnamese strings (Tiếng Việt).
|
|
2
|
+
#
|
|
3
|
+
# Written by hand, in the register of a Vietnamese product or support team:
|
|
4
|
+
# short and plain, with the words people already say in English ("email", "slide",
|
|
5
|
+
# "tab") left as they are. The keys and every %{variable} match senren.en.yml;
|
|
6
|
+
# test/i18n_catalog_test.rb fails if they stop matching.
|
|
7
|
+
#
|
|
8
|
+
# Copy this file to config/locales/ (bin/rails senren:locales vi), then change any
|
|
9
|
+
# wording you like - it is your file. A key you delete falls back to the English.
|
|
10
|
+
vi:
|
|
11
|
+
senren:
|
|
12
|
+
shared:
|
|
13
|
+
open: "Mở"
|
|
14
|
+
close: "Đóng"
|
|
15
|
+
accordion:
|
|
16
|
+
section: "Mục %{number}"
|
|
17
|
+
api_key_field:
|
|
18
|
+
label: "Khóa API"
|
|
19
|
+
reveal: "Hiện"
|
|
20
|
+
hide: "Ẩn"
|
|
21
|
+
copy: "Sao chép"
|
|
22
|
+
copied_status: "%{label} xong"
|
|
23
|
+
app_shell:
|
|
24
|
+
skip_to_content: "Chuyển đến nội dung chính"
|
|
25
|
+
breadcrumb:
|
|
26
|
+
label: "Đường dẫn"
|
|
27
|
+
bulk_action_bar:
|
|
28
|
+
items: "mục"
|
|
29
|
+
selected: "Đã chọn %{count} %{item_label}"
|
|
30
|
+
ready: "Đã chọn xong"
|
|
31
|
+
calendar:
|
|
32
|
+
title: "%{month} năm %{year}"
|
|
33
|
+
months:
|
|
34
|
+
january: "Tháng 1"
|
|
35
|
+
february: "Tháng 2"
|
|
36
|
+
march: "Tháng 3"
|
|
37
|
+
april: "Tháng 4"
|
|
38
|
+
may: "Tháng 5"
|
|
39
|
+
june: "Tháng 6"
|
|
40
|
+
july: "Tháng 7"
|
|
41
|
+
august: "Tháng 8"
|
|
42
|
+
september: "Tháng 9"
|
|
43
|
+
october: "Tháng 10"
|
|
44
|
+
november: "Tháng 11"
|
|
45
|
+
december: "Tháng 12"
|
|
46
|
+
weekdays:
|
|
47
|
+
sun: "CN"
|
|
48
|
+
mon: "T2"
|
|
49
|
+
tue: "T3"
|
|
50
|
+
wed: "T4"
|
|
51
|
+
thu: "T5"
|
|
52
|
+
fri: "T6"
|
|
53
|
+
sat: "T7"
|
|
54
|
+
carousel:
|
|
55
|
+
label: "Trình chiếu"
|
|
56
|
+
previous: "Slide trước"
|
|
57
|
+
next: "Slide sau"
|
|
58
|
+
go_to: "Đến slide %{number}"
|
|
59
|
+
status: "Slide %{current} trên %{total}"
|
|
60
|
+
cart:
|
|
61
|
+
title: "Giỏ hàng"
|
|
62
|
+
empty: "Giỏ hàng của bạn đang trống."
|
|
63
|
+
checkout: "Thanh toán"
|
|
64
|
+
subtotal: "Tạm tính"
|
|
65
|
+
remove: "Xóa"
|
|
66
|
+
quantity_group: "Số lượng %{name}"
|
|
67
|
+
decrease: "Giảm số lượng %{name}"
|
|
68
|
+
increase: "Tăng số lượng %{name}"
|
|
69
|
+
remove_item: "Xóa %{name}"
|
|
70
|
+
clipboard:
|
|
71
|
+
copy: "Sao chép"
|
|
72
|
+
copied: "Đã sao chép"
|
|
73
|
+
copied_status: "Đã sao chép vào bộ nhớ tạm"
|
|
74
|
+
collapsible:
|
|
75
|
+
details: "Chi tiết"
|
|
76
|
+
combobox:
|
|
77
|
+
placeholder: "Tìm kiếm..."
|
|
78
|
+
command:
|
|
79
|
+
placeholder: "Nhập lệnh..."
|
|
80
|
+
label: "Menu lệnh"
|
|
81
|
+
empty: "Không tìm thấy kết quả."
|
|
82
|
+
data_table:
|
|
83
|
+
empty: "Không có dữ liệu."
|
|
84
|
+
sort: "Sắp xếp"
|
|
85
|
+
date_picker:
|
|
86
|
+
placeholder: "Chọn ngày"
|
|
87
|
+
today: "Hôm nay"
|
|
88
|
+
clear: "Xóa"
|
|
89
|
+
filter_bar:
|
|
90
|
+
label: "Bộ lọc"
|
|
91
|
+
invite_member_dialog:
|
|
92
|
+
title: "Mời đồng nghiệp"
|
|
93
|
+
description: "Gửi lời mời tham gia không gian làm việc này."
|
|
94
|
+
role_member: "Thành viên"
|
|
95
|
+
role_admin: "Quản trị viên"
|
|
96
|
+
button: "Mời thành viên"
|
|
97
|
+
email: "Email"
|
|
98
|
+
email_placeholder: "ten@congty.com"
|
|
99
|
+
role: "Vai trò"
|
|
100
|
+
cancel: "Hủy"
|
|
101
|
+
send: "Gửi lời mời"
|
|
102
|
+
pagination:
|
|
103
|
+
label: "Phân trang"
|
|
104
|
+
previous: "Trước"
|
|
105
|
+
next: "Sau"
|
|
106
|
+
product_card:
|
|
107
|
+
add_to_cart: "Thêm vào giỏ"
|
|
108
|
+
out_of_stock: "Hết hàng"
|
|
109
|
+
no_image: "Chưa có ảnh"
|
|
110
|
+
rich_text_editor_lite:
|
|
111
|
+
label: "Nội dung"
|
|
112
|
+
placeholder: "Nhập nội dung..."
|
|
113
|
+
link_prompt: "Dán một URL"
|
|
114
|
+
toolbar:
|
|
115
|
+
paragraph: "Đoạn văn"
|
|
116
|
+
heading_1: "Tiêu đề 1"
|
|
117
|
+
heading_2: "Tiêu đề 2"
|
|
118
|
+
heading_3: "Tiêu đề 3"
|
|
119
|
+
bold: "In đậm"
|
|
120
|
+
italic: "In nghiêng"
|
|
121
|
+
create_link: "Tạo liên kết"
|
|
122
|
+
bulleted_list: "Danh sách dấu đầu dòng"
|
|
123
|
+
numbered_list: "Danh sách đánh số"
|
|
124
|
+
align_left: "Căn trái"
|
|
125
|
+
align_center: "Căn giữa"
|
|
126
|
+
align_right: "Căn phải"
|
|
127
|
+
justify: "Căn đều"
|
|
128
|
+
toolbar_short:
|
|
129
|
+
link: "Liên kết"
|
|
130
|
+
list: "Danh sách"
|
|
131
|
+
left: "Trái"
|
|
132
|
+
center: "Giữa"
|
|
133
|
+
right: "Phải"
|
|
134
|
+
justify: "Đều"
|
|
135
|
+
search_input:
|
|
136
|
+
placeholder: "Tìm kiếm..."
|
|
137
|
+
label: "Tìm kiếm"
|
|
138
|
+
sidebar:
|
|
139
|
+
brand: "Senren"
|
|
140
|
+
label: "Điều hướng chính"
|
|
141
|
+
toggle: "Bật/tắt thanh bên"
|
|
142
|
+
tabs:
|
|
143
|
+
label: "Các tab"
|
|
144
|
+
tab: "Tab %{number}"
|
|
145
|
+
theme_toggle:
|
|
146
|
+
label: "Đổi giao diện"
|
|
147
|
+
light: "Giao diện sáng"
|
|
148
|
+
dark: "Giao diện tối"
|
|
149
|
+
top_nav:
|
|
150
|
+
label: "Điều hướng chung"
|
|
151
|
+
brand: "Senren"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: senren-ui
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- vutt
|
|
@@ -55,9 +55,11 @@ files:
|
|
|
55
55
|
- Rakefile
|
|
56
56
|
- docs/components.md
|
|
57
57
|
- docs/hot_reload.md
|
|
58
|
+
- docs/i18n.md
|
|
58
59
|
- docs/performance_testing.md
|
|
59
60
|
- docs/visual_style.md
|
|
60
61
|
- lib/commands/senren/add/add_command.rb
|
|
62
|
+
- lib/commands/senren/locales/locales_command.rb
|
|
61
63
|
- lib/generators/senren/component/component_generator.rb
|
|
62
64
|
- lib/generators/senren/component/templates/component.html.erb.tt
|
|
63
65
|
- lib/generators/senren/component/templates/component.rb.tt
|
|
@@ -81,6 +83,7 @@ files:
|
|
|
81
83
|
- lib/senren/rails/engine.rb
|
|
82
84
|
- lib/senren/rails/host_paths.rb
|
|
83
85
|
- lib/senren/rails/llms_writer.rb
|
|
86
|
+
- lib/senren/rails/locale_installer.rb
|
|
84
87
|
- lib/senren/rails/marker_block.rb
|
|
85
88
|
- lib/senren/rails/registry.rb
|
|
86
89
|
- lib/senren/rails/safe_write.rb
|
|
@@ -244,6 +247,8 @@ files:
|
|
|
244
247
|
- templates/controllers/tabs_controller.js
|
|
245
248
|
- templates/controllers/theme_toggle_controller.js
|
|
246
249
|
- templates/controllers/tooltip_controller.js
|
|
250
|
+
- templates/locales/senren.en.yml
|
|
251
|
+
- templates/locales/senren.vi.yml
|
|
247
252
|
homepage: https://www.senren-ui.dev/
|
|
248
253
|
licenses:
|
|
249
254
|
- MIT
|