@beehexa/design-rules 2611.3.3 → 2611.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.
- package/README.md +1 -1
- package/dist/AGENTS.md +1 -7
- package/dist/catalog.json +153 -125
- package/dist/docs/scripts/color-pairs.mjs +5 -1
- package/dist/docs/scripts/token-utils.mjs +16 -1
- package/dist/docs/src/components/ColorDemo.astro +5 -5
- package/dist/docs/src/components/ElevationDemo.astro +196 -0
- package/dist/docs/src/components/LayoutDemo.astro +1 -1
- package/dist/docs/src/components/OpacityDemo.astro +95 -0
- package/dist/docs/src/components/ShapeDemo.astro +11 -10
- package/dist/docs/src/components/ShapePin.astro +5 -3
- package/dist/docs/src/components/ZIndexDemo.astro +102 -0
- package/dist/docs/src/content/foundations/styles/border.mdx +3 -3
- package/dist/docs/src/content/foundations/styles/color/usage.mdx +11 -4
- package/dist/docs/src/content/foundations/styles/data-visualization.mdx +74 -6
- package/dist/docs/src/content/foundations/styles/elevation.mdx +66 -3
- package/dist/docs/src/content/foundations/styles/icons/usage.mdx +9 -6
- package/dist/docs/src/content/foundations/styles/layout/app-frame.mdx +10 -0
- package/dist/docs/src/content/foundations/styles/opacity.mdx +43 -5
- package/dist/docs/src/content/foundations/styles/size-and-density.mdx +7 -0
- package/dist/docs/src/content/foundations/styles/typography/code.mdx +1 -1
- package/dist/docs/src/content/foundations/styles/z-index.mdx +63 -5
- package/dist/docs/src/content/tools/ant-design-vue-theme.mdx +125 -18
- package/dist/docs/src/content/tools/application-content.mdx +42 -0
- package/dist/docs/src/content/tools/editors.mdx +27 -0
- package/dist/docs/src/content/tools/mermaid.mdx +95 -0
- package/dist/docs/src/content/tools/vueflow.mdx +121 -0
- package/dist/docs/src/content-vi/foundations/styles/border.mdx +3 -3
- package/dist/docs/src/content-vi/foundations/styles/color/usage.mdx +11 -4
- package/dist/docs/src/content-vi/foundations/styles/data-visualization.mdx +75 -6
- package/dist/docs/src/content-vi/foundations/styles/elevation.mdx +75 -0
- package/dist/docs/src/content-vi/foundations/styles/icons/usage.mdx +9 -6
- package/dist/docs/src/content-vi/foundations/styles/layout/app-frame.mdx +10 -0
- package/dist/docs/src/content-vi/foundations/styles/opacity.mdx +43 -5
- package/dist/docs/src/content-vi/foundations/styles/size-and-density.mdx +7 -0
- package/dist/docs/src/content-vi/foundations/styles/typography/code.mdx +1 -1
- package/dist/docs/src/content-vi/foundations/styles/z-index.mdx +63 -5
- package/dist/docs/src/lib/token-descriptions-vi.ts +21 -5
- package/dist/docs/src/styles/chrome.css +14 -14
- package/dist/docs/src/styles/color.css +19 -32
- package/dist/docs/src/styles/docs.css +18 -34
- package/dist/docs/src/styles/elevation.css +83 -0
- package/dist/docs/src/styles/global.css +1 -10
- package/dist/docs/src/styles/icons.css +11 -15
- package/dist/docs/src/styles/kit.css +112 -0
- package/dist/docs/src/styles/layout.css +1 -6
- package/dist/docs/src/styles/opacity.css +43 -0
- package/dist/docs/src/styles/shapes.css +15 -19
- package/dist/docs/src/styles/tokens.css +1282 -3
- package/dist/docs/src/styles/tokens.js +358 -3
- package/dist/docs/src/styles/typography.css +4 -7
- package/dist/docs/src/styles/zindex.css +56 -0
- package/dist/docs/tokens/border.json +1 -1
- package/dist/docs/tokens/color.json +57 -3
- package/dist/docs/tokens/content.json +19 -0
- package/dist/docs/tokens/diagram.json +48 -0
- package/dist/docs/tokens/editor.json +129 -0
- package/dist/docs/tokens/elevation.json +15 -5
- package/dist/docs/tokens/flow.json +497 -0
- package/dist/docs/tokens/opacity.json +9 -0
- package/dist/docs/tokens/resize.json +67 -0
- package/dist/docs/tokens/size.json +6 -0
- package/dist/docs/tokens/spacing.json +4 -4
- package/dist/docs/tokens/typography.json +5 -0
- package/dist/docs/tokens/visualization.json +123 -0
- package/dist/docs/tokens/z-index.json +49 -0
- package/dist/index.js +153 -125
- package/package.json +1 -1
|
@@ -7,13 +7,17 @@
|
|
|
7
7
|
|
|
8
8
|
export const roles = ['danger', 'warning', 'success', 'info'];
|
|
9
9
|
|
|
10
|
-
const surfaces = ['surface', 'surface.page', 'surface.subtle'];
|
|
10
|
+
const surfaces = ['surface', 'surface.page', 'surface.subtle', 'surface.overlay'];
|
|
11
11
|
const neutralFills = [
|
|
12
12
|
'background.neutral',
|
|
13
13
|
'background.neutral.hover',
|
|
14
14
|
'background.neutral.subtle.hover',
|
|
15
15
|
'background.selected',
|
|
16
16
|
'background.selected.hover',
|
|
17
|
+
'surface.overlay.hover',
|
|
18
|
+
'surface.overlay.pressed',
|
|
19
|
+
'surface.overlay.selected',
|
|
20
|
+
'surface.overlay.selected.hover',
|
|
17
21
|
];
|
|
18
22
|
|
|
19
23
|
/** @type {Array<{ fg: string; on: string[]; min: number }>} */
|
|
@@ -92,7 +92,9 @@ export function createTokenModel(flatTokens) {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/** Same selectors and alias-preserving declarations for site and packages. */
|
|
95
|
-
|
|
95
|
+
// `scopes` adds .bh-scope-light and .bh-scope-dark for side-by-side light and dark examples on the
|
|
96
|
+
// docs site. The npm package leaves them out.
|
|
97
|
+
export function renderTokenCss(flatTokens, { pixels = false, scopes = false } = {}) {
|
|
96
98
|
const units = (value) => pixels
|
|
97
99
|
? value.replace(/(-?(?:\d*\.)?\d+)rem\b/g, (_, number) => `${Number(number) * 16}px`)
|
|
98
100
|
: value;
|
|
@@ -102,6 +104,14 @@ export function renderTokenCss(flatTokens, { pixels = false } = {}) {
|
|
|
102
104
|
const viTokens = flatTokens.filter((token) => token.vi !== undefined);
|
|
103
105
|
const vi = viTokens.map((token) => decl(token, token.vi));
|
|
104
106
|
const reset = viTokens.map((token) => decl(token, token.value));
|
|
107
|
+
// A scope must redeclare every colour-related token: a var() reference is resolved where it is
|
|
108
|
+
// declared, so inheriting the :root values would keep the page theme. Type tokens stay out, so
|
|
109
|
+
// lang="vi" still wins.
|
|
110
|
+
const scopeLight = flatTokens.filter((token) => !token.name.startsWith('font.')).map((token) => decl(token, token.value));
|
|
111
|
+
const scopeCss = scopes ? [
|
|
112
|
+
`.bh-scope-light {\n${scopeLight.join('\n')}\n color-scheme: light;\n}`,
|
|
113
|
+
`.bh-scope-dark {\n${scopeLight.join('\n')}\n${dark.join('\n')}\n color-scheme: dark;\n}`,
|
|
114
|
+
] : [];
|
|
105
115
|
return [
|
|
106
116
|
'/* Generated from beehexa.design tokens/*.json. Do not edit by hand. */',
|
|
107
117
|
`:root {\n${light.join('\n')}\n}`,
|
|
@@ -109,6 +119,11 @@ export function renderTokenCss(flatTokens, { pixels = false } = {}) {
|
|
|
109
119
|
`@media (prefers-color-scheme: dark) {\n :root:not([data-theme='light']) {\n${dark.map((line) => ` ${line}`).join('\n')}\n }\n}`,
|
|
110
120
|
`:lang(vi) {\n${vi.join('\n')}\n}`,
|
|
111
121
|
`[lang]:not(:lang(vi)) {\n${reset.join('\n')}\n}`,
|
|
122
|
+
...scopeCss,
|
|
123
|
+
...(flatTokens.some(token => token.name === 'font.features') ? [
|
|
124
|
+
'/* Preserve source character variants through semantic font shorthands. */',
|
|
125
|
+
'*, ::before, ::after { font-feature-settings: var(--bh-font-features) !important; }',
|
|
126
|
+
] : []),
|
|
112
127
|
'',
|
|
113
128
|
].join('\n');
|
|
114
129
|
}
|
|
@@ -63,10 +63,10 @@ const descVi: Record<string, string> = {
|
|
|
63
63
|
'color.background.disabled': 'Nền của control bị vô hiệu.',
|
|
64
64
|
'color.background.brand.subtle': 'Bề mặt và ghi chú thương hiệu.',
|
|
65
65
|
'color.background.brand.bold': 'Nền vàng thương hiệu. Chữ xám ghi bên trên (text.on-brand). Không có nút màu vàng.',
|
|
66
|
-
'color.surface': 'Card, panel
|
|
66
|
+
'color.surface': 'Card, panel. Sáng hơn nền trang một bậc ở giao diện tối.',
|
|
67
67
|
'color.surface.page': 'Nền trang.',
|
|
68
|
-
'color.surface.subtle': '
|
|
69
|
-
'color.surface.inverse': 'Bề mặt đảo màu: tooltip
|
|
68
|
+
'color.surface.subtle': 'Header toàn cục và sidebar cùng một bề mặt; drawer điều hướng mobile, header của bảng, vùng nền nhạt.',
|
|
69
|
+
'color.surface.inverse': 'Bề mặt đảo màu: tooltip. Chữ bên trên: text.inverse.',
|
|
70
70
|
'color.surface.scrim': 'Lớp phủ sau dialog và drawer.',
|
|
71
71
|
'color.border': 'Viền mặc định: đường phân cách, card, bảng.',
|
|
72
72
|
'color.border.bold': 'Viền của ô nhập, checkbox và select. 3:1 (WCAG 1.4.11) trên mọi bề mặt và nền trung tính, kể cả dòng được chọn.',
|
|
@@ -186,7 +186,7 @@ const statusRoles = [
|
|
|
186
186
|
// Token reference: every role and component token split into the four parts of its name,
|
|
187
187
|
// color.{property}.{role}.{emphasis}.{state}. A part that is left out takes its default.
|
|
188
188
|
const PROPS = ['text', 'icon', 'link', 'surface', 'background', 'border', 'skeleton', 'code'];
|
|
189
|
-
const ROLES = ['neutral', 'brand', 'danger', 'warning', 'success', 'info', 'inverse', 'disabled', 'page', 'scrim', 'on-bold', 'on-brand', 'background', 'text'];
|
|
189
|
+
const ROLES = ['neutral', 'brand', 'danger', 'warning', 'success', 'info', 'inverse', 'disabled', 'page', 'overlay', 'scrim', 'on-bold', 'on-brand', 'background', 'text'];
|
|
190
190
|
const EMPHASIS = ['subtle', 'subtlest', 'bold'];
|
|
191
191
|
const STATES = ['hover', 'pressed', 'selected', 'focus'];
|
|
192
192
|
const SCALE_NAMES = Object.keys(scaleNames);
|
|
@@ -427,7 +427,7 @@ const actions = [
|
|
|
427
427
|
{kind === 'labels' && (
|
|
428
428
|
<div class="c-labels">
|
|
429
429
|
<figure class="c-label-set">
|
|
430
|
-
<figcaption><b>{L('Label', 'Nhãn')}</b> · {L('outlined, for
|
|
430
|
+
<figcaption><b>{L('Label', 'Nhãn')}</b> · {L('outlined, for statuses inside tables, lists and cards', 'có viền, cho trạng thái trong bảng, danh sách và card')}</figcaption>
|
|
431
431
|
<div class="c-label-row">
|
|
432
432
|
<span class="bh-label">{L('Default', 'Mặc định')}</span>
|
|
433
433
|
<span class="bh-label is-brand">Early access</span>
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Illustrations for the Elevation page. Every surface is a colour token and every shadow an
|
|
3
|
+
// elevation token, so each figure shows the real values. Pins point at the part a token sets,
|
|
4
|
+
// as on the Radius and Border pages. bh-scope-light / bh-scope-dark force a theme for side-by-side views.
|
|
5
|
+
import '../styles/layout.css';
|
|
6
|
+
import '../styles/shapes.css';
|
|
7
|
+
import '../styles/elevation.css';
|
|
8
|
+
import { langOf } from '../lib/i18n';
|
|
9
|
+
import Pin from './ShapePin.astro';
|
|
10
|
+
import Check from '@lucide/astro/icons/check';
|
|
11
|
+
import ChevronDown from '@lucide/astro/icons/chevron-down';
|
|
12
|
+
import Info from '@lucide/astro/icons/info';
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
kind: 'hero' | 'level' | 'dark' | 'states' | 'dodont';
|
|
16
|
+
/** level: 'page' | 'raised' | 'overlay' | 'modal'. dodont: 'pair' | 'flat' | 'own' | 'border'. */
|
|
17
|
+
item?: string;
|
|
18
|
+
}
|
|
19
|
+
const { kind, item } = Astro.props;
|
|
20
|
+
const vi = langOf(Astro.url.pathname) === 'vi';
|
|
21
|
+
const L = (en: string, viText: string) => (vi ? viText : en);
|
|
22
|
+
const jobs = [
|
|
23
|
+
['Store A → ERP', L('Running · 2 min ago', 'Đang chạy · 2 phút trước')],
|
|
24
|
+
['Store B → ' + L('Accounting', 'Kế toán'), L('Paused', 'Tạm dừng')],
|
|
25
|
+
];
|
|
26
|
+
const levels = [
|
|
27
|
+
{ id: 'raised', name: 'Raised', token: 'shadow.raised', use: L('Cards', 'Card') },
|
|
28
|
+
{ id: 'overlay', name: 'Overlay', token: 'shadow.overlay', use: L('Menus, popovers, toasts', 'Menu, popover, toast') },
|
|
29
|
+
{ id: 'modal', name: 'Modal', token: 'shadow.modal', use: L('Dialogs, drawers', 'Dialog, drawer') },
|
|
30
|
+
];
|
|
31
|
+
const menuRows = [L('Run now', 'Chạy ngay'), L('Pause', 'Tạm dừng'), L('Edit mapping', 'Sửa mapping')];
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
{kind === 'hero' && (
|
|
35
|
+
<div class="el-hero sh-root">
|
|
36
|
+
<figure class="el-view">
|
|
37
|
+
<div class="el-front" aria-hidden="true">
|
|
38
|
+
<span class="el-plate is-page"><b>Page</b></span>
|
|
39
|
+
{levels.map((l) => <span class={`el-plate is-${l.id}`}><b>{l.name}</b></span>)}
|
|
40
|
+
</div>
|
|
41
|
+
<figcaption>{L('From the front: the shadow grows with the height.', 'Nhìn từ trước: càng cao, bóng càng lớn.')}</figcaption>
|
|
42
|
+
</figure>
|
|
43
|
+
<figure class="el-view">
|
|
44
|
+
<div class="el-side" aria-hidden="true">
|
|
45
|
+
{levels.slice().reverse().map((l) => (
|
|
46
|
+
<span class={`el-bar is-${l.id}`}><i></i><code>{l.token}</code><em>{l.use}</em></span>
|
|
47
|
+
))}
|
|
48
|
+
<span class="el-ground"><code>color.surface.page</code></span>
|
|
49
|
+
</div>
|
|
50
|
+
<figcaption>{L('From the side: three heights above the page.', 'Nhìn từ cạnh: ba độ cao so với mặt trang.')}</figcaption>
|
|
51
|
+
</figure>
|
|
52
|
+
</div>
|
|
53
|
+
)}
|
|
54
|
+
|
|
55
|
+
{kind === 'level' && item === 'page' && (
|
|
56
|
+
<div class="sh-ex-grid is-one sh-root">
|
|
57
|
+
<div class="sh-ex el-ex">
|
|
58
|
+
<Pin solid label={`${L('Border', 'Viền')}: color.border`} at="bottom" len="300" wide>
|
|
59
|
+
<div class="sh-frame" role="img" aria-label={L('A table panel on the page, with a border and no shadow', 'Một panel bảng nằm trên trang, có viền và không có bóng')}>
|
|
60
|
+
<header>{L('Sync logs', 'Nhật ký đồng bộ')}</header>
|
|
61
|
+
<div class="sh-table">
|
|
62
|
+
<span><em>10:42:07</em>{L('Order #10293 to ERP', 'Đơn #10293 sang ERP')}<em>{L('Synced', 'Đã đồng bộ')}</em></span>
|
|
63
|
+
<span><em>10:42:11</em>{L('Order #10295 to ERP', 'Đơn #10295 sang ERP')}<em>{L('Synced', 'Đã đồng bộ')}</em></span>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</Pin>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
)}
|
|
70
|
+
|
|
71
|
+
{kind === 'level' && item === 'raised' && (
|
|
72
|
+
<div class="sh-ex-grid is-one sh-root">
|
|
73
|
+
<div class="sh-ex el-ex is-pin-left">
|
|
74
|
+
<Pin solid label={`${L('Shadow', 'Bóng')}: elevation.shadow.raised`} at="bottom" len="300">
|
|
75
|
+
<Pin solid label={`${L('Background', 'Nền')}: color.surface`} at="inside-left" inset="100" len="1000">
|
|
76
|
+
<div class="el-card"><b>{jobs[0][0]}</b><span>{jobs[0][1]}</span></div>
|
|
77
|
+
</Pin>
|
|
78
|
+
</Pin>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
)}
|
|
82
|
+
|
|
83
|
+
{kind === 'level' && item === 'overlay' && (
|
|
84
|
+
<div class="sh-ex-grid is-one sh-root">
|
|
85
|
+
<div class="sh-ex el-ex is-top is-pin-left">
|
|
86
|
+
<div class="el-anchor">
|
|
87
|
+
<span class="sp-btn el-btn-icon">{L('Actions', 'Thao tác')}<ChevronDown size={16} aria-hidden="true" /></span>
|
|
88
|
+
<Pin solid label={`${L('Shadow', 'Bóng')}: elevation.shadow.overlay`} at="bottom" len="300">
|
|
89
|
+
<Pin solid label={`${L('Background', 'Nền')}: color.surface.overlay`} at="inside-left" inset="050" len="1000">
|
|
90
|
+
<span class="el-menu">{menuRows.map((r, i) => <span class={i === 0 ? 'is-on' : undefined}>{r}</span>)}</span>
|
|
91
|
+
</Pin>
|
|
92
|
+
</Pin>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
<div class="sh-ex el-ex is-pin-left">
|
|
96
|
+
<Pin solid label={`${L('Shadow', 'Bóng')}: elevation.shadow.overlay`} at="bottom" len="300">
|
|
97
|
+
<Pin solid label={`${L('Background', 'Nền')}: color.surface.overlay`} at="inside-left" inset="100" len="1000">
|
|
98
|
+
<span class="el-toast is-info"><Info size={16} aria-hidden="true" />{L('Sync started for 3 jobs', 'Đã bắt đầu đồng bộ 3 job')}</span>
|
|
99
|
+
</Pin>
|
|
100
|
+
</Pin>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
)}
|
|
104
|
+
|
|
105
|
+
{kind === 'level' && item === 'modal' && (
|
|
106
|
+
<div class="sh-ex-grid is-one sh-root">
|
|
107
|
+
<div class="sh-ex el-ex el-modal-ex is-pin-left">
|
|
108
|
+
<div class="el-page" aria-hidden="true">
|
|
109
|
+
<span class="el-lines"><i></i><i></i><i></i></span>
|
|
110
|
+
<div class="el-scrim"></div>
|
|
111
|
+
</div>
|
|
112
|
+
<Pin solid label={`${L('Shadow', 'Bóng')}: elevation.shadow.modal`} at="bottom" len="300">
|
|
113
|
+
<Pin solid label={`${L('Background', 'Nền')}: color.surface.overlay`} at="inside-left" inset="100" len="1000">
|
|
114
|
+
<div class="el-dialog" role="img" aria-label={L('A dialog over the dimmed page', 'Một dialog nằm trên trang đã bị phủ mờ')}>
|
|
115
|
+
<b>{L('Delete connection?', 'Xoá kết nối?')}</b>
|
|
116
|
+
<span>{L('Sync history is kept for 30 days.', 'Lịch sử đồng bộ được giữ 30 ngày.')}</span>
|
|
117
|
+
<span class="el-actions"><span class="sp-btn">{L('Cancel', 'Huỷ')}</span><span class="sp-btn is-primary">{L('Delete', 'Xoá')}</span></span>
|
|
118
|
+
</div>
|
|
119
|
+
</Pin>
|
|
120
|
+
</Pin>
|
|
121
|
+
<span class="el-scrim-pin"><Pin solid label={`${L('Background', 'Nền')}: color.surface.scrim`} at="bottom" len="200"><i class="el-dot"></i></Pin></span>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
)}
|
|
125
|
+
|
|
126
|
+
{kind === 'dark' && (
|
|
127
|
+
<div class="el-themes is-stack sh-root">
|
|
128
|
+
{['light', 'dark'].map((mode) => (
|
|
129
|
+
<figure class={`el-theme bh-scope-${mode}`}>
|
|
130
|
+
<figcaption>{mode === 'light' ? 'Light' : 'Dark'}</figcaption>
|
|
131
|
+
<div class="el-theme-stage">
|
|
132
|
+
<Pin solid label={`${L('Background', 'Nền')}: color.surface.page`} at="corner" len="200"><span class="el-dot is-page"></span></Pin>
|
|
133
|
+
<Pin solid label={`${L('Background', 'Nền')}: color.surface`} at="inside-left" inset="100" len="1000">
|
|
134
|
+
<div class="el-card is-wide"><b>{jobs[0][0]}</b><span>{jobs[0][1]}</span></div>
|
|
135
|
+
</Pin>
|
|
136
|
+
<Pin solid label={`${L('Background', 'Nền')}: color.surface.overlay`} at="inside-left" inset="050" len="1000">
|
|
137
|
+
<span class="el-menu">{menuRows.slice(0, 2).map((r) => <span>{r}</span>)}</span>
|
|
138
|
+
</Pin>
|
|
139
|
+
</div>
|
|
140
|
+
</figure>
|
|
141
|
+
))}
|
|
142
|
+
</div>
|
|
143
|
+
)}
|
|
144
|
+
|
|
145
|
+
{kind === 'states' && (
|
|
146
|
+
<div class="el-themes is-stack sh-root">
|
|
147
|
+
{['light', 'dark'].map((mode) => (
|
|
148
|
+
<figure class={`el-theme bh-scope-${mode}`}>
|
|
149
|
+
<figcaption>{mode === 'light' ? 'Light' : 'Dark'}</figcaption>
|
|
150
|
+
<div class="el-theme-stage is-col">
|
|
151
|
+
<span class="el-menu is-list" role="img" aria-label={L('A list of destinations with a hovered row and a selected row', 'Danh sách điểm đích có một dòng đang được rê chuột và một dòng đang chọn')}>
|
|
152
|
+
<span>CRM</span>
|
|
153
|
+
<Pin solid label={`${L('Background', 'Nền')}: color.surface.overlay.hover`} at="inside-left" inset="050" len="1000"><span class="is-on">Marketplace</span></Pin>
|
|
154
|
+
<Pin solid label={`${L('Background', 'Nền')}: color.surface.overlay.selected`} at="inside-left" inset="050" len="1000"><span class="is-sel">ERP<Check size={16} aria-hidden="true" /></span></Pin>
|
|
155
|
+
<span>{L('Warehouse', 'Kho')}</span>
|
|
156
|
+
</span>
|
|
157
|
+
</div>
|
|
158
|
+
</figure>
|
|
159
|
+
))}
|
|
160
|
+
</div>
|
|
161
|
+
)}
|
|
162
|
+
|
|
163
|
+
{kind === 'dodont' && (
|
|
164
|
+
<div class="sp-dd sh-root">
|
|
165
|
+
<figure class="sp-dd-panel is-do">
|
|
166
|
+
<figcaption><span aria-hidden="true">✓</span> {L('Do', 'Nên')}</figcaption>
|
|
167
|
+
<div class:list={['sp-dd-stage', { 'bh-scope-dark': item === 'pair' }]}>
|
|
168
|
+
{item === 'pair' && <span class="el-menu">{menuRows.map((r, i) => <span class={i === 1 ? 'is-on' : undefined}>{r}</span>)}</span>}
|
|
169
|
+
{item === 'flat' && <div class="el-panel"><b>{L('Sync logs', 'Nhật ký đồng bộ')}</b><span>{L('128 orders today', '128 đơn hôm nay')}</span></div>}
|
|
170
|
+
{item === 'own' && <span class="el-menu">{menuRows.map((r) => <span>{r}</span>)}</span>}
|
|
171
|
+
{item === 'border' && <span class="el-menu">{menuRows.map((r) => <span>{r}</span>)}</span>}
|
|
172
|
+
</div>
|
|
173
|
+
<p>
|
|
174
|
+
{item === 'pair' && L('Inside a menu, use the overlay state colours, such as color.surface.overlay.hover.', 'Bên trong menu, dùng màu trạng thái của overlay, ví dụ color.surface.overlay.hover.')}
|
|
175
|
+
{item === 'flat' && L('Keep panels, tables and page sections flat. A border is enough to separate them.', 'Để panel, bảng và các phần của trang phẳng. Một đường viền là đủ để tách chúng.')}
|
|
176
|
+
{item === 'own' && L('Use the shadow token for the level. It changes with the theme.', 'Dùng token bóng của đúng mức. Token tự đổi theo theme.')}
|
|
177
|
+
{item === 'border' && L('Let the surface and the shadow set the menu apart.', 'Để nền và bóng tách menu khỏi trang.')}
|
|
178
|
+
</p>
|
|
179
|
+
</figure>
|
|
180
|
+
<figure class="sp-dd-panel is-dont">
|
|
181
|
+
<figcaption><span aria-hidden="true">✕</span> {L('Don’t', 'Không nên')}</figcaption>
|
|
182
|
+
<div class:list={['sp-dd-stage', { 'bh-scope-dark': item === 'pair' }]}>
|
|
183
|
+
{item === 'pair' && <span class="el-menu is-wrong-surface">{menuRows.map((r, i) => <span class={i === 1 ? 'is-on' : undefined}>{r}</span>)}</span>}
|
|
184
|
+
{item === 'flat' && <div class="el-panel is-shadowed"><b>{L('Sync logs', 'Nhật ký đồng bộ')}</b><span>{L('128 orders today', '128 đơn hôm nay')}</span></div>}
|
|
185
|
+
{item === 'own' && <span class="el-menu is-own">{menuRows.map((r) => <span>{r}</span>)}</span>}
|
|
186
|
+
{item === 'border' && <span class="el-menu is-bordered">{menuRows.map((r) => <span>{r}</span>)}</span>}
|
|
187
|
+
</div>
|
|
188
|
+
<p>
|
|
189
|
+
{item === 'pair' && L('Don’t use the page’s hover colour inside a menu. In dark mode it is the same colour as the menu, so the hovered row disappears.', 'Không dùng màu hover của trang bên trong menu. Ở dark mode, màu này trùng với nền menu nên dòng đang rê chuột biến mất.')}
|
|
190
|
+
{item === 'flat' && L('Don’t give every panel a shadow. When everything floats, nothing stands out.', 'Không cho panel nào cũng có bóng. Khi mọi thứ đều nổi thì không còn gì nổi bật.')}
|
|
191
|
+
{item === 'own' && L('Don’t write your own shadow or stack two tokens. It stays dark grey in dark mode and matches no level.', 'Không tự viết bóng hay chồng hai token. Bóng tự viết không đổi theo theme và không khớp mức nào.')}
|
|
192
|
+
{item === 'border' && L('Don’t add a border to a menu, popover or dialog.', 'Không thêm viền cho menu, popover hay dialog.')}
|
|
193
|
+
</p>
|
|
194
|
+
</figure>
|
|
195
|
+
</div>
|
|
196
|
+
)}
|
|
@@ -72,7 +72,7 @@ const bands = bps.map((b, i) => ({ ...b, size: (bps[i + 1]?.min ?? b.min + 480)
|
|
|
72
72
|
<rect class="f-mark" x={1280 - pad.desktop} y={header} width={pad.desktop} height={800 - header} />
|
|
73
73
|
<rect class="f-mark" x={sidebar} y={header} width={1280 - sidebar} height={pad.desktop} />
|
|
74
74
|
<rect class="f-mark" x={sidebar} y={800 - pad.desktop} width={1280 - sidebar} height={pad.desktop} />
|
|
75
|
-
<rect class="f-
|
|
75
|
+
<rect class="f-subtle" x="0" y="0" width="1280" height={header} />
|
|
76
76
|
<rect class="f-line" x="0" y={header - 2} width="1280" height="2" />
|
|
77
77
|
<rect class="f-indicator" x="20" y="12" width="24" height="24" rx="6" />
|
|
78
78
|
<rect class="f-skel" x="52" y="16" width="88" height="16" rx="4" />
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
// Illustrations for the Opacity page. Transparency comes only from opacity.disabled and
|
|
3
|
+
// color.surface.scrim; everything else is a colour, border or size token.
|
|
4
|
+
import '../styles/layout.css';
|
|
5
|
+
import '../styles/shapes.css';
|
|
6
|
+
import '../styles/elevation.css';
|
|
7
|
+
import '../styles/opacity.css';
|
|
8
|
+
import Pin from './ShapePin.astro';
|
|
9
|
+
import { langOf } from '../lib/i18n';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
kind: 'screen' | 'tile' | 'scrim' | 'dodont';
|
|
13
|
+
/** dodont: 'container' | 'controls'. */
|
|
14
|
+
item?: string;
|
|
15
|
+
}
|
|
16
|
+
const { kind, item } = Astro.props;
|
|
17
|
+
const vi = langOf(Astro.url.pathname) === 'vi';
|
|
18
|
+
const L = (en: string, viText: string) => (vi ? viText : en);
|
|
19
|
+
const on = L('Connected', 'Đã kết nối');
|
|
20
|
+
const off = L('Turned off', 'Đã tắt');
|
|
21
|
+
const conns = [['ST', 'Store A', 'a', true], ['ER', 'ERP', 'b', true], ['AC', L('Accounting', 'Kế toán'), 'c', false], ['MK', 'Marketplace', 'd', true], ['CR', 'CRM', 'e', false], ['WH', L('Warehouse', 'Kho'), 'f', true]] as const;
|
|
22
|
+
const users = [['LN', 'Linh Nguyen', 'Admin', true], ['TP', 'Tuan Pham', 'Editor', true], ['MH', 'Mai Ho', L('Viewer · deactivated', 'Viewer · đã vô hiệu'), false]] as const;
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
{kind === 'screen' && (
|
|
26
|
+
<div class="op-wrap" role="img" aria-label={L('Connections with two turned off, and a team list with one deactivated member', 'Danh sách kết nối có hai kết nối đã tắt, và danh sách thành viên có một người đã bị vô hiệu')}>
|
|
27
|
+
<span class="op-label">{L('Connections', 'Kết nối')}</span>
|
|
28
|
+
<div class="op-grid">
|
|
29
|
+
{conns.map(([code, name, tone, isOn]) => (
|
|
30
|
+
<div class={isOn ? 'op-tile' : 'op-tile is-off'}>
|
|
31
|
+
<span class="op-tile-top"><span class={`op-logo is-${tone}`}>{code}</span><span class="op-switch"></span></span>
|
|
32
|
+
<b>{name}</b><span class="op-status">{isOn ? on : off}</span>
|
|
33
|
+
</div>
|
|
34
|
+
))}
|
|
35
|
+
</div>
|
|
36
|
+
<span class="op-label">{L('Team members', 'Thành viên')}</span>
|
|
37
|
+
<div class="op-list">
|
|
38
|
+
{users.map(([ini, name, role, isOn]) => (
|
|
39
|
+
<div class={isOn ? 'op-row' : 'op-row is-off'}><span class="op-avatar">{ini}</span><span class="op-name">{name}</span><span class="op-role">{role}</span></div>
|
|
40
|
+
))}
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
)}
|
|
44
|
+
|
|
45
|
+
{kind === 'tile' && (
|
|
46
|
+
<div class="sh-ex-grid is-one sh-root">
|
|
47
|
+
<div class="sh-ex op-ex">
|
|
48
|
+
<div class="op-tile is-off op-tile-lg" role="img" aria-label={L('A turned-off connection: the logo is faded, the text uses the disabled colour', 'Một kết nối đã tắt: logo mờ đi, chữ dùng màu disabled')}>
|
|
49
|
+
<span class="op-tile-top"><Pin solid label={`${L('Opacity', 'Độ mờ')}: opacity.disabled`} at="top" len="200"><span class="op-logo is-c">AC</span></Pin><span class="op-switch"></span></span>
|
|
50
|
+
<b>{L('Accounting', 'Kế toán')}</b>
|
|
51
|
+
<Pin solid label={`${L('Text', 'Chữ')}: color.text.disabled`} at="bottom" len="300"><span class="op-status">{off}</span></Pin>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
)}
|
|
56
|
+
|
|
57
|
+
{kind === 'scrim' && (
|
|
58
|
+
<div class="el-themes sh-root">
|
|
59
|
+
{['light', 'dark'].map((mode) => (
|
|
60
|
+
<figure class={`el-theme bh-scope-${mode}`}>
|
|
61
|
+
<figcaption>{mode === 'light' ? L('Light: graphite at 40%', 'Light: graphite 40%') : L('Dark: black at 60%', 'Dark: đen 60%')}</figcaption>
|
|
62
|
+
<div class="op-scrim-box" role="img" aria-label={L('A dialog over the scrim', 'Dialog nằm trên lớp phủ mờ')}>
|
|
63
|
+
<div class="op-lines"><span style="width: 80%"></span><span style="width: 60%"></span><span style="width: 70%"></span></div>
|
|
64
|
+
<div class="op-scrim"></div>
|
|
65
|
+
<div class="op-dialog">Dialog</div>
|
|
66
|
+
<span class="op-scrim-pin"><Pin solid label={`${L('Background', 'Nền')}: color.surface.scrim`} at="bottom" len="200"><i class="el-dot"></i></Pin></span>
|
|
67
|
+
</div>
|
|
68
|
+
</figure>
|
|
69
|
+
))}
|
|
70
|
+
</div>
|
|
71
|
+
)}
|
|
72
|
+
|
|
73
|
+
{kind === 'dodont' && (
|
|
74
|
+
<div class="sp-dd sh-root">
|
|
75
|
+
{['do', 'dont'].map((side) => (
|
|
76
|
+
<figure class={`sp-dd-panel is-${side}`}>
|
|
77
|
+
<figcaption><span aria-hidden="true">{side === 'do' ? '✓' : '✕'}</span> {side === 'do' ? L('Do', 'Nên') : L('Don’t', 'Không nên')}</figcaption>
|
|
78
|
+
<div class="sp-dd-stage">
|
|
79
|
+
{item === 'container' && (
|
|
80
|
+
<div class={side === 'do' ? 'op-tile is-off' : 'op-tile is-wrong'}><span class="op-tile-top"><span class="op-logo is-c">AC</span><span class="op-switch"></span></span><b>{L('Accounting', 'Kế toán')}</b><span class="op-status">{off}</span></div>
|
|
81
|
+
)}
|
|
82
|
+
{item === 'controls' && (
|
|
83
|
+
<div class="op-band"><span class="op-band-text">{L('Sync paused for 2 stores', 'Đã tạm dừng đồng bộ 2 cửa hàng')}</span><span class={side === 'do' ? 'sp-btn op-btn-off' : 'sp-btn is-primary op-btn-faded'}>{L('Resume', 'Tiếp tục')}</span></div>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
86
|
+
<p>
|
|
87
|
+
{item === 'container' && side === 'do' && L('Fade the logo only. The card keeps its border, and the text uses the disabled colour.', 'Chỉ làm mờ logo. Card giữ nguyên viền, chữ dùng màu disabled.')}
|
|
88
|
+
{item === 'container' && side === 'dont' && L('Don’t fade the whole card. Its border and text fade too, and the page shows through.', 'Không làm mờ cả card. Viền và chữ cũng mờ theo, và nền trang lộ ra phía sau.')}
|
|
89
|
+
{item === 'controls' && side === 'do' && L('Turn a control off with the disabled colours. It looks the same on any background.', 'Tắt một control bằng các màu disabled. Nó trông giống nhau trên mọi nền.')}
|
|
90
|
+
{item === 'controls' && side === 'dont' && L('Don’t fade a control with opacity. The background shows through, and the text loses contrast.', 'Không làm mờ control bằng opacity. Nền phía sau lộ ra và chữ mất độ tương phản.')}
|
|
91
|
+
</p>
|
|
92
|
+
</figure>
|
|
93
|
+
))}
|
|
94
|
+
</div>
|
|
95
|
+
)}
|
|
@@ -7,6 +7,7 @@ import { tokensByPrefix } from '../lib/tokens';
|
|
|
7
7
|
import { tokenDescriptionsVi } from '../lib/token-descriptions-vi';
|
|
8
8
|
import { langOf } from '../lib/i18n';
|
|
9
9
|
import Pin from './ShapePin.astro';
|
|
10
|
+
import CircleAlert from '@lucide/astro/icons/circle-alert';
|
|
10
11
|
|
|
11
12
|
interface Props {
|
|
12
13
|
kind: 'radius-scale' | 'radius-use' | 'nesting' | 'focus-radius' | 'border-scale' | 'border-use' | 'dodont';
|
|
@@ -85,7 +86,7 @@ const tick = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-
|
|
|
85
86
|
<div class="sh-ex"><Pin label="radius.100" r="var(--bh-radius-100)"><span class="sp-btn is-primary">{L('Connect', 'Kết nối')}</span></Pin></div>
|
|
86
87
|
<div class="sh-ex"><Pin label="radius.100" r="var(--bh-radius-100)"><span class="sp-input" style="width: 14rem"><span style="width: var(--bh-space-150)"></span><span>mystore.example.com</span></span></Pin></div>
|
|
87
88
|
<div class="sh-ex"><Pin label="radius.100" r="var(--bh-radius-100)"><span class="sh-tip">{L('Copied to clipboard', 'Đã sao chép')}</span></Pin></div>
|
|
88
|
-
<div class="sh-ex"><Pin label="radius.100" r="var(--bh-radius-100)"><span class="
|
|
89
|
+
<div class="sh-ex"><Pin label="radius.100" r="var(--bh-radius-100)"><span class="kit-banner is-danger"><CircleAlert size={16} aria-hidden="true" />{L('Sync failed for 12 orders. Retrying in 5 minutes.', 'Đồng bộ lỗi 12 đơn hàng. Thử lại sau 5 phút.')}</span></Pin></div>
|
|
89
90
|
</Fragment>
|
|
90
91
|
)}
|
|
91
92
|
{item === '150' && (
|
|
@@ -107,10 +108,10 @@ const tick = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-
|
|
|
107
108
|
)}
|
|
108
109
|
{item === 'full' && (
|
|
109
110
|
<Fragment>
|
|
110
|
-
<div class="sh-ex"><Pin label="radius.full" r="calc(var(--bh-
|
|
111
|
-
<div class="sh-ex"><Pin label="radius.full" r="calc(var(--bh-
|
|
111
|
+
<div class="sh-ex"><Pin label="radius.full" r="calc(var(--bh-size-control-default) / 2)"><span class="sh-avatar">TN</span></Pin></div>
|
|
112
|
+
<div class="sh-ex"><Pin label="radius.full" r="calc(var(--bh-space-250) / 2)"><span class="sh-switch" role="img" aria-label={L('Switch, on', 'Switch, đang bật')}></span></Pin></div>
|
|
112
113
|
<div class="sh-ex"><Pin label="radius.full" r="calc(var(--bh-size-control-default) / 2)"><span class="sh-chip">{L('Online store', 'Cửa hàng online')}<span aria-hidden="true">×</span></span></Pin></div>
|
|
113
|
-
<div class="sh-ex"><Pin label="radius.full" r="calc(var(--bh-
|
|
114
|
+
<div class="sh-ex"><Pin label="radius.full" r="calc(var(--bh-space-250) / 2)"><span class="sh-tag is-pill">{L('Connected', 'Đã kết nối')}</span></Pin></div>
|
|
114
115
|
</Fragment>
|
|
115
116
|
)}
|
|
116
117
|
</div>
|
|
@@ -179,7 +180,7 @@ const tick = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-
|
|
|
179
180
|
)}
|
|
180
181
|
{item === 'accent' && (
|
|
181
182
|
<Fragment>
|
|
182
|
-
<div class="sh-ex is-b is-span is-left"><Pin solid label="border.width.accent" at="left" wide><span class="sh-alert"><b>{L('
|
|
183
|
+
<div class="sh-ex is-b is-span is-left"><Pin solid label="border.width.accent" at="left" wide><span class="sh-alert"><b>{L('Before the first sync', 'Trước lần đồng bộ đầu tiên')}</b><span>{L('Map the order fields. Fields without a mapping are skipped.', 'Hãy ánh xạ các trường đơn hàng. Trường chưa ánh xạ sẽ bị bỏ qua.')}</span></span></Pin></div>
|
|
183
184
|
<div class="sh-ex is-b is-span is-left"><Pin solid label="border.width.accent" at="left"><p class="sh-quote">{L('Use one radius for every control.', 'Mọi control dùng chung một radius.')}</p></Pin></div>
|
|
184
185
|
<div class="sh-ex is-b is-span is-left">
|
|
185
186
|
<span class="sh-frame">
|
|
@@ -202,9 +203,9 @@ const tick = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-
|
|
|
202
203
|
<div class="sp-dd-stage">
|
|
203
204
|
{item === 'nested' && <div class="sh-outer" style="border-radius: var(--bh-radius-200); padding: var(--bh-space-100); width: 13rem"><span class="sh-inner" style="border-radius: var(--bh-radius-100); min-height: 4rem">{L('Button group', 'Nhóm nút')}</span></div>}
|
|
204
205
|
{item === 'controls' && <span class="sh-row"><span class="sp-input" style="width: 11rem"><span style="width: var(--bh-space-150)"></span><span>{L('Search orders', 'Tìm đơn hàng')}</span></span><span class="sp-btn is-primary">{L('Search', 'Tìm')}</span></span>}
|
|
205
|
-
{item === 'corners' && <span class="sh-alert"><b>{L('
|
|
206
|
+
{item === 'corners' && <span class="sh-alert"><b>{L('Before the first sync', 'Trước lần đồng bộ đầu tiên')}</b><span>{L('Map the order fields.', 'Hãy ánh xạ các trường đơn hàng.')}</span></span>}
|
|
206
207
|
{item === 'selected' && <span class="sh-tabs"><span class="is-on">{L('Overview', 'Tổng quan')}</span><span>{L('Mappings', 'Mapping')}</span><span>{L('History', 'Lịch sử')}</span></span>}
|
|
207
|
-
{item === 'accent' && <span class="sh-alert"><b>{L('
|
|
208
|
+
{item === 'accent' && <span class="sh-alert"><b>{L('Before the first sync', 'Trước lần đồng bộ đầu tiên')}</b><span>{L('Map the order fields.', 'Hãy ánh xạ các trường đơn hàng.')}</span></span>}
|
|
208
209
|
{item === 'cards' && <span class="sh-card"><b>{L('Online store', 'Cửa hàng online')}</b><span>{L('Connected', 'Đã kết nối')}</span></span>}
|
|
209
210
|
</div>
|
|
210
211
|
<p>
|
|
@@ -221,9 +222,9 @@ const tick = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-
|
|
|
221
222
|
<div class="sp-dd-stage">
|
|
222
223
|
{item === 'nested' && <div class="sh-outer" style="border-radius: var(--bh-radius-200); padding: var(--bh-space-100); width: 13rem"><span class="sh-inner" style="border-radius: var(--bh-radius-200); min-height: 4rem">{L('Button group', 'Nhóm nút')}</span></div>}
|
|
223
224
|
{item === 'controls' && <span class="sh-row"><span class="sp-input" style="width: 11rem; border-radius: var(--bh-radius-050)"><span style="width: var(--bh-space-150)"></span><span>{L('Search orders', 'Tìm đơn hàng')}</span></span><span class="sp-btn is-primary" style="border-radius: var(--bh-radius-full)">{L('Search', 'Tìm')}</span></span>}
|
|
224
|
-
{item === 'corners' && <span class="sh-alert is-squared"><b>{L('
|
|
225
|
+
{item === 'corners' && <span class="sh-alert is-squared"><b>{L('Before the first sync', 'Trước lần đồng bộ đầu tiên')}</b><span>{L('Map the order fields.', 'Hãy ánh xạ các trường đơn hàng.')}</span></span>}
|
|
225
226
|
{item === 'selected' && <span class="sh-tabs" style="--sh-sel: var(--bh-border-width-accent)"><span class="is-on">{L('Overview', 'Tổng quan')}</span><span>{L('Mappings', 'Mapping')}</span><span>{L('History', 'Lịch sử')}</span></span>}
|
|
226
|
-
{item === 'accent' && <span class="sh-alert is-boxed"><b>{L('
|
|
227
|
+
{item === 'accent' && <span class="sh-alert is-boxed"><b>{L('Before the first sync', 'Trước lần đồng bộ đầu tiên')}</b><span>{L('Map the order fields.', 'Hãy ánh xạ các trường đơn hàng.')}</span></span>}
|
|
227
228
|
{item === 'cards' && <span class="sh-card" style="border-width: var(--bh-border-width-selected); border-color: var(--bh-color-border-bold)"><b>{L('Online store', 'Cửa hàng online')}</b><span>{L('Connected', 'Đã kết nối')}</span></span>}
|
|
228
229
|
</div>
|
|
229
230
|
<p>
|
|
@@ -231,7 +232,7 @@ const tick = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-
|
|
|
231
232
|
{item === 'controls' && L('A 4 px input next to a pill button. The row looks like two different products.', 'Ô nhập 4 px cạnh nút viên thuốc. Hàng control trông như của hai sản phẩm khác nhau.')}
|
|
232
233
|
{item === 'corners' && L('Square only the left corners. One box ends up with two radii.', 'Chỉ làm vuông hai góc trái. Một hộp có hai radius khác nhau.')}
|
|
233
234
|
{item === 'selected' && L('Use the 4 px accent for a selected tab. Accent is for status and emphasis.', 'Dùng accent 4 px cho tab đang chọn. Accent dành cho trạng thái và nhấn mạnh.')}
|
|
234
|
-
{item === 'accent' && L('Draw 4 px all the way round. The
|
|
235
|
+
{item === 'accent' && L('Draw 4 px all the way round. The box shouts and the message gets lost.', 'Vẽ 4 px quanh cả hộp. Hộp trông quá nặng và nội dung bị lấn át.')}
|
|
235
236
|
{item === 'cards' && L('Give every card a 2 px border. Nothing can show selection any more.', 'Card nào cũng viền 2 px. Không còn cách nào để báo trạng thái đang chọn.')}
|
|
236
237
|
</p>
|
|
237
238
|
</figure>
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
interface Props {
|
|
6
6
|
label: string;
|
|
7
7
|
/** corner: the bottom-left corner. bottom / top: the middle of the bottom or top edge. left: the middle of the left edge. */
|
|
8
|
-
at?: 'corner' | 'bottom' | 'top' | 'left';
|
|
8
|
+
at?: 'corner' | 'bottom' | 'top' | 'left' | 'inside' | 'inside-left';
|
|
9
|
+
/** inside / inside-left: how far in from the left edge the dot sits, as a space token step. Use these to point at a fill (a surface colour), not an edge. */
|
|
10
|
+
inset?: string;
|
|
9
11
|
/** The element's radius, e.g. var(--bh-radius-100). Draws the curve inside the hexagon. Leave out for border pins. */
|
|
10
12
|
r?: string;
|
|
11
13
|
/** Line length as a space token step, e.g. '300' for space.300. */
|
|
@@ -17,6 +19,6 @@ interface Props {
|
|
|
17
19
|
/** Line length when a left pin drops down on narrow screens. */
|
|
18
20
|
lenNarrow?: string;
|
|
19
21
|
}
|
|
20
|
-
const { label, at = 'corner', r, len = '300', wide = false, solid = false, lenNarrow } = Astro.props;
|
|
22
|
+
const { label, at = 'corner', r, len = '300', wide = false, solid = false, lenNarrow, inset = '200' } = Astro.props;
|
|
21
23
|
---
|
|
22
|
-
<span class:list={['sh-pin', { 'is-wide': wide }]}><slot /><span class:list={['sh-anno', `is-${at}`, { 'is-solid': solid }]} style={`--sh-len: var(--bh-space-${len});${lenNarrow ? ` --sh-len-n: var(--bh-space-${lenNarrow});` : ''}${r ? ` --sh-r: ${r};` : ''}`} aria-hidden="true"><i class="sh-mark">{r && <b class="sh-arc"></b>}</i><b class="sh-ln"></b><code>{label}</code></span></span>
|
|
24
|
+
<span class:list={['sh-pin', { 'is-wide': wide }]}><slot /><span class:list={['sh-anno', `is-${at}`, { 'is-solid': solid }]} style={`--sh-len: var(--bh-space-${len}); --sh-in: var(--bh-space-${inset});${lenNarrow ? ` --sh-len-n: var(--bh-space-${lenNarrow});` : ''}${r ? ` --sh-r: ${r};` : ''}`} aria-hidden="true"><i class="sh-mark">{r && <b class="sh-arc"></b>}</i><b class="sh-ln"></b><code>{label}</code></span></span>
|