@ecomcx/ecomweb-content 0.0.0-stage → 1.14.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.
- package/LICENSE +21 -0
- package/README.md +157 -2
- package/dist/block.d.ts +58 -0
- package/dist/block.js +60 -0
- package/dist/embed.d.ts +23 -0
- package/dist/embed.js +63 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/migrate.d.ts +2 -0
- package/dist/migrate.js +19 -0
- package/dist/normalize.d.ts +25 -0
- package/dist/normalize.js +146 -0
- package/dist/schema.d.ts +31 -0
- package/dist/schema.js +167 -0
- package/dist/style.d.ts +74 -0
- package/dist/style.js +285 -0
- package/dist/text.d.ts +9 -0
- package/dist/text.js +30 -0
- package/dist/types.d.ts +36 -0
- package/dist/types.js +6 -0
- package/dist/url.d.ts +7 -0
- package/dist/url.js +21 -0
- package/fixtures/all-core-nodes.json +782 -0
- package/fixtures/attr-coercion.json +219 -0
- package/fixtures/basic-blocks.json +414 -0
- package/fixtures/block-extras.json +131 -0
- package/fixtures/block-styles.json +316 -0
- package/fixtures/dynamic-blocks.json +316 -0
- package/fixtures/editor-output-nulls.json +112 -0
- package/fixtures/empty-and-newer.json +12 -0
- package/fixtures/invalid-structure.json +145 -0
- package/fixtures/layout-blocks.json +238 -0
- package/fixtures/legacy-html-string.json +17 -0
- package/fixtures/legacy-tiptap-doc.json +41 -0
- package/fixtures/plugin-blocks-preserved.json +155 -0
- package/fixtures/synced-pattern.json +80 -0
- package/package.json +44 -4
- package/style.css +161 -0
package/style.css
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Giao diện nền cho nội dung (@ecomcx/ecomweb-content) — dùng chung cho website và trình soạn.
|
|
3
|
+
* Nằm trong @layer ecx-content + mọi selector trong :where() → CSS của theme (có layer hay không) luôn thắng.
|
|
4
|
+
* Nạp file này trước CSS của theme để layer ecx-content đứng thấp nhất.
|
|
5
|
+
* Theme đổi màu bằng biến: --ecx-border, --ecx-muted, --ecx-accent, --ecx-surface, --ecx-code-bg, --ecx-code-fg.
|
|
6
|
+
*/
|
|
7
|
+
@layer ecx-content {
|
|
8
|
+
/* Preset của kiểu dáng khối (attrs.style): theme đổi bằng cách đặt lại biến (theme.json › styles) */
|
|
9
|
+
:where(:root) {
|
|
10
|
+
--ecx-spacing-xs: .25rem; --ecx-spacing-sm: .5rem; --ecx-spacing-md: 1rem; --ecx-spacing-lg: 1.5rem;
|
|
11
|
+
--ecx-spacing-xl: 2.5rem; --ecx-spacing-2xl: 4rem; --ecx-spacing-3xl: 6rem;
|
|
12
|
+
--ecx-font-size-xs: .75rem; --ecx-font-size-sm: .875rem; --ecx-font-size-md: 1rem; --ecx-font-size-lg: 1.25rem;
|
|
13
|
+
--ecx-font-size-xl: 1.5rem; --ecx-font-size-2xl: 2rem; --ecx-font-size-3xl: 2.75rem; --ecx-font-size-4xl: 3.5rem;
|
|
14
|
+
--ecx-color-primary: var(--primary, #2563eb); --ecx-color-muted: #6b7280; --ecx-color-surface: #f4f4f5;
|
|
15
|
+
--ecx-color-white: #fff; --ecx-color-black: #111;
|
|
16
|
+
--ecx-font-family-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
:where(.ecx-content) {
|
|
20
|
+
--_border: var(--ecx-border, color-mix(in srgb, currentColor 18%, transparent));
|
|
21
|
+
--_muted: var(--ecx-muted, color-mix(in srgb, currentColor 65%, transparent));
|
|
22
|
+
--_accent: var(--ecx-accent, var(--primary, currentColor));
|
|
23
|
+
--_surface: var(--ecx-surface, color-mix(in srgb, currentColor 5%, transparent));
|
|
24
|
+
overflow-wrap: break-word;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:where(.ecx-content) :where(ul, ol) { padding-left: 1.5em; }
|
|
28
|
+
:where(.ecx-content) :where(ul) { list-style: disc; }
|
|
29
|
+
:where(.ecx-content) :where(ol) { list-style: decimal; }
|
|
30
|
+
:where(.ecx-content) :where(li > p) { margin: 0; }
|
|
31
|
+
:where(.ecx-content) :where(.ecx-task-list) { list-style: none; padding-left: 0; }
|
|
32
|
+
:where(.ecx-content) :where(.ecx-task-item) { display: flex; gap: .5em; align-items: baseline; }
|
|
33
|
+
|
|
34
|
+
:where(.ecx-content) :where(blockquote) { margin: 1.5em 0; padding: .25em 0 .25em 1em; border-left: 3px solid var(--_accent); color: var(--_muted); }
|
|
35
|
+
:where(.ecx-content) :where(pre) { padding: 1em 1.25em; border-radius: 8px; overflow-x: auto; background: var(--ecx-code-bg, #18181b); color: var(--ecx-code-fg, #f4f4f5);
|
|
36
|
+
font: .875rem/1.6 ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
37
|
+
:where(.ecx-content) :where(code) { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .9em; }
|
|
38
|
+
:where(.ecx-content) :where(:not(pre) > code) { padding: .1em .35em; border-radius: 4px; background: var(--_surface); }
|
|
39
|
+
:where(.ecx-content) :where(hr) { margin: 2em 0; border: 0; border-top: 1px solid var(--_border); }
|
|
40
|
+
:where(.ecx-content) :where(a) { color: var(--_accent); text-underline-offset: 2px; }
|
|
41
|
+
:where(.ecx-content) :where(mark) { padding: 0 .1em; }
|
|
42
|
+
|
|
43
|
+
:where(.ecx-content) :where(img, video, iframe) { max-width: 100%; }
|
|
44
|
+
:where(.ecx-content) :where(img) { height: auto; }
|
|
45
|
+
:where(.ecx-content) :where(figure) { margin: 1.5em 0; }
|
|
46
|
+
:where(.ecx-content) :where(figcaption) { margin-top: .5em; font-size: .875em; color: var(--_muted); text-align: center; }
|
|
47
|
+
:where(.ecx-content) :where(.ecx-align-center) { margin-left: auto; margin-right: auto; text-align: center; }
|
|
48
|
+
:where(.ecx-content) :where(.ecx-align-left) { float: left; margin: .25em 1.5em 1em 0; max-width: 50%; }
|
|
49
|
+
:where(.ecx-content) :where(.ecx-align-right) { float: right; margin: .25em 0 1em 1.5em; max-width: 50%; }
|
|
50
|
+
|
|
51
|
+
:where(.ecx-content) :where(.ecx-table) { overflow-x: auto; margin: 1.5em 0; }
|
|
52
|
+
:where(.ecx-content) :where(table) { width: 100%; border-collapse: collapse; }
|
|
53
|
+
:where(.ecx-content) :where(th, td) { box-sizing: border-box; height: 2.5em; padding: .5em .75em; border: 1px solid var(--_border); vertical-align: top; text-align: start; }
|
|
54
|
+
:where(.ecx-content) :where(th) { background: var(--_surface); font-weight: 600; }
|
|
55
|
+
:where(.ecx-content) :where(th, td) > :where(p) { margin: 0; }
|
|
56
|
+
:where(.ecx-content) :where(tfoot td, tfoot th) { font-weight: 600; background: var(--_surface); }
|
|
57
|
+
:where(.ecx-content) :where(table.is-fixed) { table-layout: fixed; }
|
|
58
|
+
|
|
59
|
+
:where(.ecx-content) :where(.ecx-youtube) { position: relative; aspect-ratio: 16 / 9; margin: 1.5em 0; }
|
|
60
|
+
:where(.ecx-content) :where(.ecx-youtube iframe) { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; border-radius: 8px; }
|
|
61
|
+
:where(.ecx-content) :where(.ecx-file) { margin: 1.5em 0; }
|
|
62
|
+
:where(.ecx-content) :where(.ecx-file-link) { display: inline-block; padding: .5em .9em; border: 1px solid var(--_border); border-radius: 8px; text-decoration: none; }
|
|
63
|
+
|
|
64
|
+
:where(.ecx-content) :where(.ecx-columns, .ecx-group, .ecx-callout, .ecx-embed) { margin: 1.5em 0; }
|
|
65
|
+
:where(.ecx-content) :where(.ecx-column, .ecx-group, .ecx-callout) > :where(:first-child) { margin-top: 0; }
|
|
66
|
+
:where(.ecx-content) :where(.ecx-column, .ecx-group, .ecx-callout) > :where(:last-child) { margin-bottom: 0; }
|
|
67
|
+
|
|
68
|
+
/* Template trang "full-width": nội dung trải hết chiều ngang dù nằm trong khung giới hạn của theme */
|
|
69
|
+
:where(.ecx-full-width) { width: 100vw; margin-inline: calc(50% - 50vw); }
|
|
70
|
+
|
|
71
|
+
/* Bộ khối cơ bản (1.9) */
|
|
72
|
+
:where(.ecx-spacer) { display: block; }
|
|
73
|
+
:where(.ecx-buttons-group) { display: flex; flex-wrap: wrap; gap: .75em; margin: 1.5em 0; }
|
|
74
|
+
:where(.ecx-buttons-group.is-center) { justify-content: center; }
|
|
75
|
+
:where(.ecx-buttons-group.is-right) { justify-content: flex-end; }
|
|
76
|
+
:where(.ecx-buttons-group.is-space-between) { justify-content: space-between; }
|
|
77
|
+
:where(.ecx-cover) { position: relative; display: flex; align-items: center; overflow: hidden; margin: 1.5em 0; padding: 2rem 1.5rem; color: #fff; background-size: cover; background-position: center; }
|
|
78
|
+
:where(.ecx-cover.is-top) { align-items: flex-start; }
|
|
79
|
+
:where(.ecx-cover.is-bottom) { align-items: flex-end; }
|
|
80
|
+
:where(.ecx-cover.is-fixed) { background-attachment: fixed; }
|
|
81
|
+
:where(.ecx-cover-img) { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
|
|
82
|
+
:where(.ecx-cover-overlay) { position: absolute; inset: 0; }
|
|
83
|
+
:where(.ecx-cover-inner) { position: relative; width: 100%; max-width: 960px; margin-inline: auto; }
|
|
84
|
+
:where(.ecx-cover-inner) > :where(:first-child) { margin-top: 0; }
|
|
85
|
+
:where(.ecx-cover-inner) > :where(:last-child) { margin-bottom: 0; }
|
|
86
|
+
:where(.ecx-cover) :where(a:not(.ecx-button)) { color: inherit; }
|
|
87
|
+
:where(.ecx-media-text) { display: grid; gap: 2rem; align-items: center; margin: 1.5em 0; grid-template-columns: var(--ecx-media-width, 50%) 1fr; }
|
|
88
|
+
:where(.ecx-media-text.is-right) { grid-template-columns: 1fr var(--ecx-media-width, 50%); }
|
|
89
|
+
:where(.ecx-media-text.is-right) > :where(.ecx-media-text-media) { order: 2; }
|
|
90
|
+
:where(.ecx-media-text.is-top) { align-items: start; }
|
|
91
|
+
:where(.ecx-media-text.is-bottom) { align-items: end; }
|
|
92
|
+
:where(.ecx-media-text-media) :where(img) { display: block; width: 100%; height: auto; border-radius: 8px; }
|
|
93
|
+
:where(.ecx-media-text-content) > :where(:first-child) { margin-top: 0; }
|
|
94
|
+
@media (max-width: 640px) {
|
|
95
|
+
:where(.ecx-media-text.is-stack, .ecx-media-text.is-stack.is-right) { grid-template-columns: 1fr; }
|
|
96
|
+
:where(.ecx-media-text.is-stack.is-right) > :where(.ecx-media-text-media) { order: 0; }
|
|
97
|
+
}
|
|
98
|
+
:where(.ecx-pullquote) { margin: 2em 0; padding: 1.5em 0; border-block: 3px solid currentColor; text-align: center; }
|
|
99
|
+
:where(.ecx-pullquote) :where(blockquote) { margin: 0; padding: 0; border: 0; color: inherit; font-size: 1.5em; line-height: 1.4; }
|
|
100
|
+
:where(.ecx-pullquote) :where(figcaption) { margin-top: 1em; font-size: .875em; text-transform: uppercase; letter-spacing: .05em; }
|
|
101
|
+
:where(.ecx-details) { margin: 1em 0; padding: .75em 1em; border: 1px solid var(--_border, color-mix(in srgb, currentColor 18%, transparent)); border-radius: 8px; }
|
|
102
|
+
:where(.ecx-details) > :where(summary) { cursor: pointer; font-weight: 600; }
|
|
103
|
+
:where(.ecx-details[open]) > :where(summary) { margin-bottom: .5em; }
|
|
104
|
+
:where(.ecx-social) { display: flex; flex-wrap: wrap; gap: .5em; margin: 1em 0; padding: 0; list-style: none; }
|
|
105
|
+
:where(.ecx-social.is-center) { justify-content: center; }
|
|
106
|
+
:where(.ecx-social.is-right) { justify-content: flex-end; }
|
|
107
|
+
:where(.ecx-social) :where(a) { display: inline-flex; align-items: center; gap: .4em; padding: .5em; border-radius: 999px; background: var(--_surface, color-mix(in srgb, currentColor 6%, transparent)); color: inherit; text-decoration: none; font-size: 1.1em; font-weight: 600; line-height: 1; }
|
|
108
|
+
:where(.ecx-social.has-labels) :where(a) { padding: .5em .9em; font-size: .875em; }
|
|
109
|
+
:where(.ecx-social) :where(svg) { width: 1.1em; height: 1.1em; flex: none; }
|
|
110
|
+
:where(.ecx-social.is-small) :where(a) { font-size: .85em; }
|
|
111
|
+
:where(.ecx-social.is-large) :where(a) { font-size: 1.5em; }
|
|
112
|
+
:where(.ecx-toc) { margin: 1.5em 0; padding: 1em 1.25em; border: 1px solid var(--_border, color-mix(in srgb, currentColor 18%, transparent)); border-radius: 8px; }
|
|
113
|
+
:where(.ecx-toc-title) { margin: 0 0 .5em; font-weight: 700; }
|
|
114
|
+
:where(.ecx-toc) :where(ol) { margin: 0; padding-left: 1.25em; }
|
|
115
|
+
:where(.ecx-pre) { white-space: pre-wrap; font-family: var(--ecx-font-family-mono, ui-monospace, monospace); font-size: .9em; }
|
|
116
|
+
|
|
117
|
+
/* Biến thể kiểu có sẵn (attrs.blockStyle → .ecx-is-<tên>) */
|
|
118
|
+
:where(.ecx-is-stripes) :where(tbody tr:nth-child(odd) > td) { background: var(--_surface, color-mix(in srgb, currentColor 5%, transparent)); }
|
|
119
|
+
:where(.ecx-is-stripes) :where(th, td) { border-inline: 0; }
|
|
120
|
+
:where(.ecx-is-rounded img, img.ecx-is-rounded) { border-radius: 16px; }
|
|
121
|
+
:where(.ecx-is-circle img, img.ecx-is-circle) { border-radius: 50%; aspect-ratio: 1; object-fit: cover; }
|
|
122
|
+
:where(blockquote.ecx-is-plain) { border: 0; padding-left: 0; font-style: normal; }
|
|
123
|
+
:where(hr.ecx-is-dots) { border: 0; text-align: center; overflow: visible; }
|
|
124
|
+
:where(hr.ecx-is-dots)::before { content: "· · ·"; letter-spacing: 1em; font-size: 1.25em; color: var(--_muted, currentColor); }
|
|
125
|
+
:where(hr.ecx-is-wide) { border-top-width: 3px; }
|
|
126
|
+
:where(.ecx-is-pill .ecx-button, .ecx-button.ecx-is-pill) { border-radius: 999px !important; }
|
|
127
|
+
:where(.ecx-group.ecx-is-card) { padding: 1.5rem; border: 1px solid var(--_border, color-mix(in srgb, currentColor 15%, transparent)); border-radius: 12px; box-shadow: 0 4px 20px rgb(0 0 0 / .06); }
|
|
128
|
+
|
|
129
|
+
/* Khối động (template / Trình dựng) */
|
|
130
|
+
:where(.ecx-site-title) { margin: 0; font-weight: 700; }
|
|
131
|
+
:where(.ecx-site-title) :where(a) { color: inherit; text-decoration: none; }
|
|
132
|
+
:where(.ecx-site-tagline, .ecx-copyright, .ecx-post-date, .ecx-post-terms, .ecx-post-author) { color: var(--_muted, inherit); }
|
|
133
|
+
:where(.ecx-navigation-menu) :where(ul) { display: flex; flex-wrap: wrap; gap: .25em 1.25em; margin: 0; padding: 0; list-style: none; }
|
|
134
|
+
:where(.ecx-navigation-menu) :where(ul ul) { display: none; }
|
|
135
|
+
:where(.ecx-navigation-menu) :where(a) { color: inherit; text-decoration: none; }
|
|
136
|
+
:where(.ecx-navigation-vertical .ecx-navigation-menu) :where(ul) { flex-direction: column; }
|
|
137
|
+
:where(.ecx-navigation-toggle) { display: none; }
|
|
138
|
+
:where(.ecx-navigation-toggle) > :where(summary) { list-style: none; cursor: pointer; font-size: 1.4em; line-height: 1; }
|
|
139
|
+
:where(.ecx-navigation-toggle[open] .ecx-navigation-menu) :where(ul) { flex-direction: column; padding-top: .5em; }
|
|
140
|
+
@media (max-width: 640px) {
|
|
141
|
+
:where(.ecx-navigation.has-mobile) > :where(.ecx-navigation-items) { display: none; }
|
|
142
|
+
:where(.ecx-navigation.has-mobile) > :where(.ecx-navigation-toggle) { display: block; }
|
|
143
|
+
}
|
|
144
|
+
:where(.ecx-post-template) { margin: 0; padding: 0; list-style: none; }
|
|
145
|
+
:where(.ecx-post-template:not(.is-grid)) > :where(.ecx-post + .ecx-post) { margin-top: 2em; }
|
|
146
|
+
:where(.ecx-post) > :where(:first-child) { margin-top: 0; }
|
|
147
|
+
|
|
148
|
+
:where(.ecx-form) { display: grid; gap: 1em; max-width: 36rem; margin: 1.5em 0; }
|
|
149
|
+
:where(.ecx-form) :where(.ecx-form-field) { display: grid; gap: .35em; margin: 0; }
|
|
150
|
+
:where(.ecx-form) :where(.ecx-form-boolean) { display: block; }
|
|
151
|
+
:where(.ecx-form) :where(input:not([type="checkbox"], [type="radio"]), select, textarea) {
|
|
152
|
+
width: 100%; box-sizing: border-box; padding: .55em .75em; border: 1px solid var(--ecx-border, color-mix(in srgb, currentColor 25%, transparent));
|
|
153
|
+
border-radius: 8px; background: transparent; color: inherit; font: inherit; }
|
|
154
|
+
:where(.ecx-form) :where(input:focus-visible, select:focus-visible, textarea:focus-visible) { outline: 2px solid var(--ecx-accent, var(--primary, currentColor)); outline-offset: 1px; }
|
|
155
|
+
:where(.ecx-form) :where([aria-invalid="true"]) { border-color: #dc2626; }
|
|
156
|
+
:where(.ecx-form) :where(button[type="submit"]) { justify-self: start; padding: .6em 1.2em; border: 0; border-radius: 8px; cursor: pointer; font: inherit; font-weight: 600;
|
|
157
|
+
background: var(--ecx-button-bg, var(--primary, #18181b)); color: var(--ecx-button-fg, #fff); }
|
|
158
|
+
:where(.ecx-form) :where(button[type="submit"]:disabled) { opacity: .6; cursor: progress; }
|
|
159
|
+
:where(.ecx-form) :where(.ecx-form-error) { color: #dc2626; font-size: .875em; }
|
|
160
|
+
:where(.ecx-form-success) { padding: .75em 1em; border-radius: 8px; background: color-mix(in srgb, #16a34a 10%, transparent); }
|
|
161
|
+
}
|