@xihan-ui/styles 3.1.0 → 4.0.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.
Files changed (290) hide show
  1. package/CHANGELOG.md +470 -0
  2. package/component-tokens.d.ts +230 -60
  3. package/components.tokens.json +5156 -1557
  4. package/css/accordion.css +47 -20
  5. package/css/alert.css +16 -17
  6. package/css/anchor.css +2 -2
  7. package/css/approval.css +41 -17
  8. package/css/avatar-group.css +9 -12
  9. package/css/avatar.css +20 -18
  10. package/css/back-top.css +21 -7
  11. package/css/badge.css +5 -5
  12. package/css/breadcrumb.css +18 -16
  13. package/css/button-group.css +4 -6
  14. package/css/button.css +13 -12
  15. package/css/calendar-picker.css +178 -95
  16. package/css/calendar-range-picker.css +207 -122
  17. package/css/card.css +34 -6
  18. package/css/carousel.css +94 -46
  19. package/css/cartesian-chart.css +11 -11
  20. package/css/cascader.css +51 -39
  21. package/css/checkbox-group.css +9 -6
  22. package/css/checkbox.css +5 -4
  23. package/css/citation.css +9 -4
  24. package/css/clipboard.css +20 -4
  25. package/css/code-view.css +6 -6
  26. package/css/collapsible.css +29 -14
  27. package/css/color-field.css +4 -4
  28. package/css/color-picker.css +77 -23
  29. package/css/color-slider.css +10 -8
  30. package/css/color-swatch-picker.css +14 -9
  31. package/css/combobox.css +26 -14
  32. package/css/command.css +14 -9
  33. package/css/context-menu.css +10 -5
  34. package/css/date-field.css +12 -6
  35. package/css/date-picker.css +178 -109
  36. package/css/date-range-picker.css +199 -130
  37. package/css/description.css +10 -6
  38. package/css/descriptions.css +47 -19
  39. package/css/dialog.css +50 -35
  40. package/css/diff-view.css +8 -8
  41. package/css/drawer.css +75 -21
  42. package/css/editable.css +15 -41
  43. package/css/empty-state.css +21 -3
  44. package/css/field-array.css +5 -2
  45. package/css/field.css +17 -18
  46. package/css/fieldset.css +33 -13
  47. package/css/file-upload.css +66 -33
  48. package/css/float-button.css +60 -35
  49. package/css/floating-panel.css +1 -1
  50. package/css/form.css +30 -16
  51. package/css/graph-chart.css +2 -2
  52. package/css/grid-list.css +1 -1
  53. package/css/highlight.css +5 -5
  54. package/css/hover-card.css +19 -12
  55. package/css/image-viewer.css +77 -27
  56. package/css/image.css +13 -5
  57. package/css/infinite-scroll.css +8 -4
  58. package/css/input-group.css +74 -26
  59. package/css/kbd.css +1 -1
  60. package/css/label.css +27 -11
  61. package/css/layout.css +17 -10
  62. package/css/list.css +13 -9
  63. package/css/listbox.css +12 -7
  64. package/css/loading-bar.css +3 -0
  65. package/css/mention.css +11 -9
  66. package/css/menu.css +10 -5
  67. package/css/menubar.css +13 -8
  68. package/css/message-feed.css +1 -1
  69. package/css/navigation-menu.css +2 -2
  70. package/css/notification.css +132 -49
  71. package/css/number-animation.css +2 -2
  72. package/css/number-field.css +75 -52
  73. package/css/page-header.css +64 -27
  74. package/css/pagination.css +35 -38
  75. package/css/password-input.css +12 -68
  76. package/css/pin-input.css +18 -26
  77. package/css/popconfirm.css +23 -14
  78. package/css/popover.css +18 -12
  79. package/css/progress.css +14 -13
  80. package/css/prompt-input.css +3 -3
  81. package/css/question-flow.css +41 -15
  82. package/css/radar-chart.css +6 -6
  83. package/css/radio-group.css +120 -55
  84. package/css/rating.css +32 -15
  85. package/css/select.css +16 -12
  86. package/css/separator.css +24 -6
  87. package/css/side-nav.css +29 -24
  88. package/css/signature-pad.css +23 -9
  89. package/css/skeleton.css +12 -12
  90. package/css/slider.css +77 -48
  91. package/css/sortable.css +2 -2
  92. package/css/sparkline.css +8 -2
  93. package/css/spinner.css +40 -20
  94. package/css/statistic.css +14 -14
  95. package/css/steps.css +115 -84
  96. package/css/switch.css +9 -7
  97. package/css/table.css +29 -12
  98. package/css/tabs.css +35 -12
  99. package/css/tag-group.css +17 -6
  100. package/css/tag.css +54 -29
  101. package/css/tags-input.css +39 -20
  102. package/css/text-field.css +5 -5
  103. package/css/time-field.css +4 -4
  104. package/css/time-picker.css +150 -64
  105. package/css/time-range-picker.css +91 -62
  106. package/css/timeline.css +37 -20
  107. package/css/timer.css +3 -3
  108. package/css/toggle-group.css +4 -4
  109. package/css/tool-call.css +13 -11
  110. package/css/toolbar.css +6 -5
  111. package/css/tooltip.css +16 -17
  112. package/css/tour.css +14 -7
  113. package/css/transfer.css +22 -16
  114. package/css/tree-select.css +12 -12
  115. package/css/tree.css +26 -25
  116. package/css/typography.css +28 -25
  117. package/dist/css/accordion.css +296 -0
  118. package/dist/css/affix.css +47 -0
  119. package/dist/css/alert.css +246 -0
  120. package/dist/css/anchor.css +252 -0
  121. package/dist/css/approval.css +525 -0
  122. package/dist/css/avatar-group.css +96 -0
  123. package/dist/css/avatar.css +100 -0
  124. package/dist/css/back-top.css +175 -0
  125. package/dist/css/badge.css +205 -0
  126. package/dist/css/bar-code.css +62 -0
  127. package/dist/css/breadcrumb.css +232 -0
  128. package/dist/css/button-group.css +261 -0
  129. package/dist/css/button.css +216 -0
  130. package/dist/css/calendar-picker.css +550 -0
  131. package/dist/css/calendar-range-picker.css +639 -0
  132. package/dist/css/card.css +249 -0
  133. package/dist/css/carousel.css +726 -0
  134. package/dist/css/cartesian-chart.css +830 -0
  135. package/dist/css/cascader.css +973 -0
  136. package/dist/css/checkbox-group.css +361 -0
  137. package/dist/css/checkbox.css +258 -0
  138. package/dist/css/citation.css +475 -0
  139. package/dist/css/clipboard.css +331 -0
  140. package/dist/css/code-view.css +374 -0
  141. package/dist/css/collapsible.css +200 -0
  142. package/dist/css/color-field.css +176 -0
  143. package/dist/css/color-picker.css +649 -0
  144. package/dist/css/color-slider.css +283 -0
  145. package/dist/css/color-swatch-picker.css +250 -0
  146. package/dist/css/color-swatch.css +35 -0
  147. package/dist/css/combobox.css +578 -0
  148. package/dist/css/command.css +404 -0
  149. package/dist/css/context-menu.css +425 -0
  150. package/dist/css/date-field.css +317 -0
  151. package/dist/css/date-picker.css +931 -0
  152. package/dist/css/date-range-picker.css +949 -0
  153. package/dist/css/description.css +71 -0
  154. package/dist/css/descriptions.css +327 -0
  155. package/dist/css/dialog.css +470 -0
  156. package/dist/css/diff-view.css +513 -0
  157. package/dist/css/download-trigger.css +151 -0
  158. package/dist/css/drawer.css +606 -0
  159. package/dist/css/editable.css +269 -0
  160. package/dist/css/empty-state.css +181 -0
  161. package/dist/css/field-array.css +229 -0
  162. package/dist/css/field.css +165 -0
  163. package/dist/css/fieldset.css +122 -0
  164. package/dist/css/file-upload.css +462 -0
  165. package/dist/css/flex.css +441 -0
  166. package/dist/css/float-button.css +579 -0
  167. package/dist/css/floating-panel.css +429 -0
  168. package/dist/css/focus.css +46 -0
  169. package/dist/css/forced-colors.css +93 -0
  170. package/dist/css/form.css +407 -0
  171. package/dist/css/funnel-chart.css +106 -0
  172. package/dist/css/graph-chart.css +205 -0
  173. package/dist/css/grid-list.css +235 -0
  174. package/dist/css/grid.css +1201 -0
  175. package/dist/css/heatmap.css +552 -0
  176. package/dist/css/hierarchy-chart.css +298 -0
  177. package/dist/css/highlight.css +41 -0
  178. package/dist/css/hover-card.css +233 -0
  179. package/dist/css/icon.css +225 -0
  180. package/dist/css/image-cropper.css +373 -0
  181. package/dist/css/image-viewer.css +588 -0
  182. package/dist/css/image.css +106 -0
  183. package/dist/css/infinite-scroll.css +81 -0
  184. package/dist/css/input-group.css +323 -0
  185. package/dist/css/json-viewer.css +379 -0
  186. package/dist/css/kbd.css +72 -0
  187. package/dist/css/label.css +94 -0
  188. package/dist/css/layers.css +7 -0
  189. package/dist/css/layout.css +379 -0
  190. package/dist/css/liquid.css +106 -0
  191. package/dist/css/list.css +156 -0
  192. package/dist/css/listbox.css +395 -0
  193. package/dist/css/loading-bar.css +144 -0
  194. package/dist/css/log.css +306 -0
  195. package/dist/css/markdown-stream.css +149 -0
  196. package/dist/css/marquee.css +378 -0
  197. package/dist/css/masonry.css +70 -0
  198. package/dist/css/matrix-code.css +67 -0
  199. package/dist/css/mention.css +395 -0
  200. package/dist/css/menu.css +369 -0
  201. package/dist/css/menubar.css +461 -0
  202. package/dist/css/message-feed.css +318 -0
  203. package/dist/css/navigation-menu.css +513 -0
  204. package/dist/css/notification.css +865 -0
  205. package/dist/css/number-animation.css +44 -0
  206. package/dist/css/number-field.css +275 -0
  207. package/dist/css/overlay-arrow.css +56 -0
  208. package/dist/css/page-header.css +221 -0
  209. package/dist/css/pagination.css +447 -0
  210. package/dist/css/password-input.css +335 -0
  211. package/dist/css/pie-chart.css +247 -0
  212. package/dist/css/pin-input.css +191 -0
  213. package/dist/css/pointer.css +36 -0
  214. package/dist/css/popconfirm.css +329 -0
  215. package/dist/css/popover.css +285 -0
  216. package/dist/css/progress.css +502 -0
  217. package/dist/css/prompt-input.css +260 -0
  218. package/dist/css/question-flow.css +579 -0
  219. package/dist/css/radar-chart.css +233 -0
  220. package/dist/css/radio-group.css +663 -0
  221. package/dist/css/rating.css +311 -0
  222. package/dist/css/reasoning.css +343 -0
  223. package/dist/css/reset.css +117 -0
  224. package/dist/css/resizable.css +242 -0
  225. package/dist/css/sankey-chart.css +174 -0
  226. package/dist/css/scroll-area.css +240 -0
  227. package/dist/css/scrollbar.css +204 -0
  228. package/dist/css/select.css +616 -0
  229. package/dist/css/separator.css +140 -0
  230. package/dist/css/side-nav.css +481 -0
  231. package/dist/css/signature-pad.css +193 -0
  232. package/dist/css/skeleton.css +161 -0
  233. package/dist/css/slider.css +403 -0
  234. package/dist/css/sortable.css +228 -0
  235. package/dist/css/sparkline.css +170 -0
  236. package/dist/css/spinner.css +256 -0
  237. package/dist/css/splitter.css +159 -0
  238. package/dist/css/statistic.css +137 -0
  239. package/dist/css/steps.css +658 -0
  240. package/dist/css/switch.css +353 -0
  241. package/dist/css/table.css +1162 -0
  242. package/dist/css/tabs.css +967 -0
  243. package/dist/css/tag-group.css +258 -0
  244. package/dist/css/tag.css +335 -0
  245. package/dist/css/tags-input.css +341 -0
  246. package/dist/css/text-field.css +197 -0
  247. package/dist/css/time-field.css +277 -0
  248. package/dist/css/time-picker.css +793 -0
  249. package/dist/css/time-range-picker.css +775 -0
  250. package/dist/css/timeline.css +440 -0
  251. package/dist/css/timer.css +123 -0
  252. package/dist/css/timestamp.css +34 -0
  253. package/dist/css/toggle-group.css +424 -0
  254. package/dist/css/toggle.css +146 -0
  255. package/dist/css/tone.css +189 -0
  256. package/dist/css/tool-call.css +431 -0
  257. package/dist/css/toolbar.css +366 -0
  258. package/dist/css/tooltip.css +217 -0
  259. package/dist/css/tour.css +446 -0
  260. package/dist/css/transfer.css +644 -0
  261. package/dist/css/tree-select.css +878 -0
  262. package/dist/css/tree.css +734 -0
  263. package/dist/css/truncate.css +108 -0
  264. package/dist/css/typography.css +475 -0
  265. package/dist/css/undefined.css +58 -0
  266. package/dist/css/virtualizer.css +166 -0
  267. package/dist/css/visually-hidden.css +20 -0
  268. package/dist/css/watermark.css +82 -0
  269. package/dist/family/action-control.css +493 -0
  270. package/dist/family/chart.css +537 -0
  271. package/dist/family/check-mark.css +94 -0
  272. package/dist/family/choice-card.css +97 -0
  273. package/dist/family/collection-item.css +768 -0
  274. package/dist/family/field-chrome.css +296 -0
  275. package/dist/family/loading-ring.css +102 -0
  276. package/dist/family/material.css +72 -0
  277. package/dist/family/menu-choice.css +56 -0
  278. package/dist/family/motion.css +363 -0
  279. package/dist/family/swatch.css +59 -0
  280. package/dist/family/tag-list.css +65 -0
  281. package/family/action-control.css +33 -36
  282. package/family/chart.css +57 -0
  283. package/family/collection-item.css +12 -8
  284. package/family/field-chrome.css +28 -19
  285. package/family/loading-ring.css +20 -13
  286. package/family/swatch.css +4 -4
  287. package/family/tag-list.css +6 -0
  288. package/index.css +10349 -8756
  289. package/index.unlayered.css +10350 -8758
  290. package/package.json +165 -164
@@ -0,0 +1,225 @@
1
+ /*
2
+ * Copyright (c) 2021-Present XiHanFun and contributors.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ */
5
+
6
+ /* 定义 icon 样式。 */
7
+
8
+ @layer xihan.components {
9
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
10
+ .xh-scope-icon {
11
+ --xh-icon-skin: 1;
12
+ }
13
+
14
+ /*
15
+ * 根 <svg>。直径、描边粗细、行内位置都由这里给,记录只带几何。
16
+ * 不写 fill / stroke:记录里那两条呈现属性取 currentColor,改这里会把
17
+ * 描边图标与实心图标一起改掉;皮肤只给 color,配色随上下文流下来。
18
+ */
19
+ .xh-scope-icon[data-part='root'] {
20
+ display: inline-block;
21
+ flex: none;
22
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-md));
23
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-md));
24
+
25
+ /* 替换元素的基线就是自身下边缘,落在文字基线上时整块图形都在基线以上、看着偏高。
26
+ 往下挪一小段,单位是 em,跟着相邻文字的字号一起缩放 */
27
+ vertical-align: var(--xh-icon-shift, var(--xh-glyph-baseline-shift));
28
+ color: var(--xh-icon-fg, currentColor);
29
+
30
+ /* 记录把 stroke-width 写成根上的呈现属性,呈现属性的层叠优先级低于任何 CSS 规则,
31
+ 这条与下面两档因此能接管粗细,再沿继承落到每个图元上 */
32
+ stroke-width: var(--xh-icon-stroke, var(--xh-glyph-stroke-regular));
33
+ }
34
+
35
+ /* 声明了 display 就盖掉了 UA 的 [hidden]{display:none},收起态得自己还回去 */
36
+ .xh-scope-icon[data-part='root'][hidden] {
37
+ display: none;
38
+ }
39
+
40
+ /* 八档直径,缺省档 md 写在上面的基础规则里。
41
+ 每一档都把 --xh-icon-size 排在自己的档值前面:这个槽是外层统一图元直径的通道,
42
+ 档值直接写终值的话,写了 data-size 的那一枚就脱离外层控制,作者在祖先上的覆盖也改不动它 */
43
+ .xh-scope-icon[data-part='root'][data-size='text'] {
44
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-text));
45
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-text));
46
+ }
47
+
48
+ .xh-scope-icon[data-part='root'][data-size='sm'] {
49
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-sm));
50
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-sm));
51
+ }
52
+
53
+ .xh-scope-icon[data-part='root'][data-size='md'] {
54
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-md));
55
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-md));
56
+ }
57
+
58
+ .xh-scope-icon[data-part='root'][data-size='lg'] {
59
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-lg));
60
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-lg));
61
+ }
62
+
63
+ .xh-scope-icon[data-part='root'][data-size='xl'] {
64
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-xl));
65
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-xl));
66
+ }
67
+
68
+ .xh-scope-icon[data-part='root'][data-size='2xl'] {
69
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-2xl));
70
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-2xl));
71
+ }
72
+
73
+ .xh-scope-icon[data-part='root'][data-size='3xl'] {
74
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-3xl));
75
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-3xl));
76
+ }
77
+
78
+ .xh-scope-icon[data-part='root'][data-size='4xl'] {
79
+ inline-size: var(--xh-icon-size, var(--xh-glyph-size-4xl));
80
+ block-size: var(--xh-icon-size, var(--xh-glyph-size-4xl));
81
+ }
82
+
83
+ /* 三档描边,缺省档同样写在基础规则里;--xh-icon-stroke 同样排在档值前面 */
84
+ .xh-scope-icon[data-part='root'][data-weight='light'] {
85
+ stroke-width: var(--xh-icon-stroke, var(--xh-glyph-stroke-light));
86
+ }
87
+
88
+ .xh-scope-icon[data-part='root'][data-weight='bold'] {
89
+ stroke-width: var(--xh-icon-stroke, var(--xh-glyph-stroke-bold));
90
+ }
91
+
92
+ /* 语气:图标没有底色,语气只落在前景上,取普通背景上表达该语气的那档文字色。
93
+ 选择器上带 [data-tone] 是必需的:语气槽会沿继承流下来,不限定在写了语气的
94
+ 那个节点上,放在语气容器里的装饰图标会跟着一起改色 */
95
+ .xh-scope-icon[data-part='root'][data-tone] {
96
+ color: var(--xh-icon-fg, var(--xh-_tone-fg, currentColor));
97
+ }
98
+
99
+ /* 旋转:四分之一圈的整数倍,是把箭头指向别处的结构性角度,不是可调幅度。
100
+ 没有过渡也没有动画——转到位就停在那儿,减弱动效那一档碰不到它 */
101
+ .xh-scope-icon[data-part='root'][data-rotate='90'] {
102
+ rotate: 90deg;
103
+ }
104
+
105
+ .xh-scope-icon[data-part='root'][data-rotate='180'] {
106
+ rotate: 180deg;
107
+ }
108
+
109
+ .xh-scope-icon[data-part='root'][data-rotate='270'] {
110
+ rotate: 270deg;
111
+ }
112
+
113
+ /* 翻转:沿轴取反,同样是静态几何。与旋转是两个独立属性,同写时自然叠加 */
114
+ .xh-scope-icon[data-part='root'][data-flip='horizontal'] {
115
+ scale: -1 1;
116
+ }
117
+
118
+ .xh-scope-icon[data-part='root'][data-flip='vertical'] {
119
+ scale: 1 -1;
120
+ }
121
+
122
+ .xh-scope-icon[data-part='root'][data-flip='both'] {
123
+ scale: -1 -1;
124
+ }
125
+
126
+ /* —— 底框 —— */
127
+ /*
128
+ * 加了框的图标是一个定直径的圆底座:框画在 <svg> 自己的盒上,图元落在内容盒里居中。
129
+ * sm / md / lg 三档框与头像同档(取同一支控件高度令牌),图元按自己的档位取字形直径,
130
+ * 内衬由两者之差算出,框换档时图元跟着一起换。
131
+ * 框里的图元不读外层统一图元直径的通道 --xh-icon-size:框自己就是一个定尺对象,
132
+ * 落在按钮、提示条这类下发图元直径的容器里也不被改小。
133
+ * 排在档位与语气之后:框接管了盒的尺寸与配色。
134
+ */
135
+ .xh-scope-icon[data-part='root'][data-frame] {
136
+ /* 三档之外的档位经两支 step 槽给出字形直径与框直径,三档本身在下面的档位块里换 */
137
+ --xh-_icon-glyph: var(--xh-icon-frame-glyph-size, var(--xh-_icon-glyph-step, var(--xh-glyph-size-md)));
138
+ --xh-_icon-frame-size: var(--xh-icon-frame-size, var(--xh-_icon-frame-step, var(--xh-control-h-md)));
139
+
140
+ inline-size: var(--xh-_icon-frame-size);
141
+ block-size: var(--xh-_icon-frame-size);
142
+ padding: calc((var(--xh-_icon-frame-size) - var(--xh-_icon-glyph)) / 2 - var(--xh-stroke-thin));
143
+ border: var(--xh-stroke-thin) solid transparent;
144
+ border-radius: var(--xh-icon-frame-radius, var(--xh-shape-circle));
145
+ }
146
+
147
+ .xh-scope-icon[data-part='root'][data-frame][data-size='sm'] {
148
+ --xh-_icon-glyph: var(--xh-icon-frame-glyph-size, var(--xh-glyph-size-sm));
149
+ --xh-_icon-frame-size: var(--xh-icon-frame-size, var(--xh-control-h-sm));
150
+ }
151
+
152
+ .xh-scope-icon[data-part='root'][data-frame][data-size='lg'] {
153
+ --xh-_icon-glyph: var(--xh-icon-frame-glyph-size, var(--xh-glyph-size-lg));
154
+ --xh-_icon-frame-size: var(--xh-icon-frame-size, var(--xh-control-h-lg));
155
+ }
156
+
157
+ /* 头像只有三档;其余档的框沿用 md 档的内衬厚度:框直径 = 本档字形 + md 档框与字形之差 */
158
+ .xh-scope-icon[data-part='root'][data-frame][data-size='text'] {
159
+ --xh-_icon-glyph-step: var(--xh-glyph-size-text);
160
+ --xh-_icon-frame-step: calc(var(--xh-glyph-size-text) + var(--xh-control-h-md) - var(--xh-glyph-size-md));
161
+ }
162
+
163
+ .xh-scope-icon[data-part='root'][data-frame][data-size='xl'] {
164
+ --xh-_icon-glyph-step: var(--xh-glyph-size-xl);
165
+ --xh-_icon-frame-step: calc(var(--xh-glyph-size-xl) + var(--xh-control-h-md) - var(--xh-glyph-size-md));
166
+ }
167
+
168
+ .xh-scope-icon[data-part='root'][data-frame][data-size='2xl'] {
169
+ --xh-_icon-glyph-step: var(--xh-glyph-size-2xl);
170
+ --xh-_icon-frame-step: calc(var(--xh-glyph-size-2xl) + var(--xh-control-h-md) - var(--xh-glyph-size-md));
171
+ }
172
+
173
+ .xh-scope-icon[data-part='root'][data-frame][data-size='3xl'] {
174
+ --xh-_icon-glyph-step: var(--xh-glyph-size-3xl);
175
+ --xh-_icon-frame-step: calc(var(--xh-glyph-size-3xl) + var(--xh-control-h-md) - var(--xh-glyph-size-md));
176
+ }
177
+
178
+ .xh-scope-icon[data-part='root'][data-frame][data-size='4xl'] {
179
+ --xh-_icon-glyph-step: var(--xh-glyph-size-4xl);
180
+ --xh-_icon-frame-step: calc(var(--xh-glyph-size-4xl) + var(--xh-control-h-md) - var(--xh-glyph-size-md));
181
+ }
182
+
183
+ /* 框的四种形态只决定颜色怎么用;用哪族颜色由 data-tone 决定,没写语气取品牌实心 / 中性。
184
+ 语气只认自己身上的 data-tone:语气槽会沿继承流下来,放在语气容器里的框不跟着改色。
185
+ 实心档在顶边画一条极浅的内高光,把这块底座衬出厚度;另外三档面上没有实心底,不画 */
186
+ .xh-scope-icon[data-part='root'][data-frame='solid'] {
187
+ background: var(--xh-icon-frame-bg, var(--xh-bg-brand));
188
+ box-shadow: var(--xh-icon-frame-shadow, var(--xh-_highlight-brand));
189
+ color: var(--xh-icon-fg, var(--xh-fg-on-brand));
190
+ }
191
+
192
+ .xh-scope-icon[data-part='root'][data-frame='solid'][data-tone] {
193
+ background: var(--xh-icon-frame-bg, var(--xh-_tone));
194
+ box-shadow: var(--xh-icon-frame-shadow, var(--xh-_highlight-tone));
195
+ color: var(--xh-icon-fg, var(--xh-_tone-on));
196
+ }
197
+
198
+ .xh-scope-icon[data-part='root'][data-frame='subtle'] {
199
+ background: var(--xh-icon-frame-bg, var(--xh-bg-subtle));
200
+ color: var(--xh-icon-fg, var(--xh-fg-default));
201
+ }
202
+
203
+ .xh-scope-icon[data-part='root'][data-frame='subtle'][data-tone] {
204
+ background: var(--xh-icon-frame-bg, var(--xh-_tone-subtle));
205
+ color: var(--xh-icon-fg, var(--xh-_tone-fg));
206
+ }
207
+
208
+ .xh-scope-icon[data-part='root'][data-frame='outline'] {
209
+ border-color: var(--xh-icon-frame-border, var(--xh-border-default));
210
+ color: var(--xh-icon-fg, var(--xh-fg-default));
211
+ }
212
+
213
+ .xh-scope-icon[data-part='root'][data-frame='outline'][data-tone] {
214
+ border-color: var(--xh-icon-frame-border, var(--xh-_tone-border));
215
+ color: var(--xh-icon-fg, var(--xh-_tone-fg));
216
+ }
217
+
218
+ .xh-scope-icon[data-part='root'][data-frame='ghost'] {
219
+ color: var(--xh-icon-fg, var(--xh-fg-default));
220
+ }
221
+
222
+ .xh-scope-icon[data-part='root'][data-frame='ghost'][data-tone] {
223
+ color: var(--xh-icon-fg, var(--xh-_tone-fg));
224
+ }
225
+ }
@@ -0,0 +1,373 @@
1
+ /*
2
+ * Copyright (c) 2021-Present XiHanFun and contributors.
3
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
4
+ */
5
+
6
+ /* 定义 image cropper 样式。 */
7
+
8
+ @import '../family/action-control.css';
9
+
10
+ @layer xihan.components {
11
+ /* 皮肤在场的标记:开发模式下按 scope 探一次,取不到就说明这份皮肤没被引入。 */
12
+ .xh-scope-image-cropper {
13
+ --xh-image-cropper-skin: 1;
14
+ }
15
+
16
+ /* 定位分工:裁切框在视口里的 left / top / width / height,以及图片与裁切框的
17
+ transform,由连接层每帧写进内联样式——那四个数是图片像素换算出来的百分比,
18
+ 只有连接层算得出来。这份皮肤一个都不碰,写了不但是死声明,还会跟内联值抢位置。
19
+
20
+ 私有槽两个,都挂在 root 上靠继承发下去:
21
+ handle-size 是把手的边长,zoom 是当前缩放倍率——裁切框整体被 scale 放大,
22
+ 把手与描边要按倍率反向缩回去,否则放到 3 倍时把手也变成三倍大、描边变成三像素粗。 */
23
+ .xh-scope-image-cropper[data-part='root'] {
24
+ --xh-_image-cropper-handle-size: var(--xh-image-cropper-handle-size, var(--xh-control-indicator-size));
25
+ --xh-_image-cropper-zoom: 1;
26
+
27
+ position: relative;
28
+ display: block;
29
+ inline-size: var(--xh-image-cropper-w, 100%);
30
+ }
31
+
32
+ /* 量坐标的那个盒子。里面装的是图片像素坐标,不是文字:裁切框与把手的落点一律写物理属性,
33
+ 不依赖这里的文字方向。overflow 收口:放大后的图片与遮罩都靠它裁掉。 */
34
+ .xh-scope-image-cropper[data-part='viewport'] {
35
+ position: relative;
36
+ display: block;
37
+ overflow: hidden;
38
+ border-radius: var(--xh-image-cropper-viewport-radius, var(--xh-shape-surface));
39
+ background: var(--xh-image-cropper-bg, var(--xh-bg-muted));
40
+ user-select: none;
41
+ }
42
+
43
+ /* 图片铺满视口、高度自适应:视口的高度因此由图片撑出来,
44
+ 裁切框的百分比坐标才与图片的像素一一对应。 */
45
+ .xh-scope-image-cropper[data-part='image'] {
46
+ display: block;
47
+ inline-size: 100%;
48
+ block-size: auto;
49
+ }
50
+
51
+ /* 裁切框。遮罩用一圈超大的实心投影把框外压暗——不必再摆四块遮罩节点,
52
+ 圆形裁切时投影也自动跟着圆角走。描边按倍率缩回去,放大时仍是一根细线。 */
53
+ .xh-scope-image-cropper[data-part='crop-area'] {
54
+ --xh-_image-cropper-corner-radius: var(--xh-shape-control);
55
+
56
+ position: absolute;
57
+ box-sizing: border-box;
58
+ border-style: solid;
59
+ border-width: calc(var(--xh-stroke-thin) / var(--xh-_image-cropper-zoom));
60
+ border-color: var(--xh-image-cropper-crop-border, var(--xh-bg-surface));
61
+ box-shadow: 0 0 0 9999px var(--xh-image-cropper-mask, var(--xh-bg-overlay));
62
+ cursor: move;
63
+ }
64
+
65
+ /* 圆形裁切取 circle 档(50%):shape 的固定长度档画出来是胶囊不是椭圆,
66
+ 裁切框的宽高由数据决定、两边通常不等长,只有百分比才随框变成椭圆;圆角只能来自语义形状令牌 */
67
+ .xh-scope-image-cropper[data-part='crop-area'][data-shape='round'] {
68
+ --xh-_image-cropper-corner-radius: var(--xh-shape-circle);
69
+
70
+ border-radius: var(--xh-image-cropper-crop-area-radius, var(--xh-shape-circle));
71
+ }
72
+
73
+ .xh-scope-image-cropper[data-part='crop-area'][data-dragging] {
74
+ cursor: grabbing;
75
+ }
76
+
77
+ .xh-scope-image-cropper[data-part='crop-area'][data-readonly]:not([data-disabled]) {
78
+ cursor: default;
79
+ }
80
+
81
+ /* 三分构图参考线:两条竖线、两条横线,落点写死在三分处,不占节点、不吃指针。
82
+ 停靠点逐条写全而不用 repeating-:重复单元从 0 起算会在框的两条边缘上各多画一根,
83
+ 那两根与裁切框的描边叠在一起,看着像描边加粗了一倍。
84
+ 线宽跟着裁切框的倍率缩回去,与描边同一口径。
85
+ 圆形裁切时参考线没有意义,收起来。 */
86
+ .xh-scope-image-cropper[data-part='grid'] {
87
+ --xh-_image-cropper-grid-w: calc(var(--xh-stroke-thin) / var(--xh-_image-cropper-zoom));
88
+
89
+ position: absolute;
90
+ inset: 0;
91
+ background-image:
92
+ linear-gradient(
93
+ to right,
94
+ transparent 0 33.3333%,
95
+ var(--xh-image-cropper-grid-line, var(--xh-bg-subtle-opaque)) 33.3333% calc(33.3333% + var(--xh-_image-cropper-grid-w)),
96
+ transparent calc(33.3333% + var(--xh-_image-cropper-grid-w)) 66.6667%,
97
+ var(--xh-image-cropper-grid-line, var(--xh-bg-subtle-opaque)) 66.6667% calc(66.6667% + var(--xh-_image-cropper-grid-w)),
98
+ transparent calc(66.6667% + var(--xh-_image-cropper-grid-w)) 100%
99
+ ),
100
+ linear-gradient(
101
+ to bottom,
102
+ transparent 0 33.3333%,
103
+ var(--xh-image-cropper-grid-line, var(--xh-bg-subtle-opaque)) 33.3333% calc(33.3333% + var(--xh-_image-cropper-grid-w)),
104
+ transparent calc(33.3333% + var(--xh-_image-cropper-grid-w)) 66.6667%,
105
+ var(--xh-image-cropper-grid-line, var(--xh-bg-subtle-opaque)) 66.6667% calc(66.6667% + var(--xh-_image-cropper-grid-w)),
106
+ transparent calc(66.6667% + var(--xh-_image-cropper-grid-w)) 100%
107
+ );
108
+ pointer-events: none;
109
+ }
110
+
111
+ .xh-scope-image-cropper[data-part='grid'][data-shape='round'] {
112
+ background-image: none;
113
+ }
114
+
115
+ /* 把手的命中区仍以裁切框边界为中心,视觉短条与折角贴住边框并向框内绘制。 */
116
+ .xh-scope-image-cropper[data-part='crop-handle'] {
117
+ --xh-_image-cropper-handle-color: var(--xh-image-cropper-handle-bg, var(--xh-bg-surface));
118
+
119
+ position: absolute;
120
+ display: block;
121
+ box-sizing: border-box;
122
+ border: 0;
123
+ background: transparent;
124
+ inline-size: var(--xh-_image-cropper-handle-size);
125
+ block-size: var(--xh-_image-cropper-handle-size);
126
+ translate: -50% -50%;
127
+ scale: calc(1 / var(--xh-_image-cropper-zoom));
128
+ }
129
+
130
+ .xh-scope-image-cropper[data-part='crop-handle']::after {
131
+ content: '';
132
+ position: absolute;
133
+ box-sizing: border-box;
134
+ border-radius: var(--xh-image-cropper-handle-radius, var(--xh-shape-pill));
135
+ background: var(--xh-_image-cropper-handle-color);
136
+ pointer-events: none;
137
+ transition:
138
+ background-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter),
139
+ border-color var(--xh-motion-duration-micro) var(--xh-motion-ease-enter);
140
+ }
141
+
142
+ /* 看得见的方块比手指小:另铺一层不可见的命中区,把它撑到最小可点尺寸。
143
+ inset 取负值即向四面外扩,方块本身更大时这个值转正、命中区仍是方块那么大。 */
144
+ .xh-scope-image-cropper[data-part='crop-handle']::before {
145
+ position: absolute;
146
+ inset: calc((var(--xh-_image-cropper-handle-size) - var(--xh-control-action-size)) / 2);
147
+ content: '';
148
+ }
149
+
150
+ /* 把手静息是白面(bg-surface),悬停从同一语义面派生一档,不切到品牌淡底;拖动中才是品牌实心。
151
+ 把手与网格线都压在照片上,取淡底的不透明档,照片深浅不一时才看得见 */
152
+ .xh-scope-image-cropper[data-part='crop-handle']:hover:not([data-disabled], [data-readonly]) {
153
+ --xh-_image-cropper-handle-color: var(--xh-image-cropper-handle-bg-hover, var(--xh-bg-subtle-opaque));
154
+ }
155
+
156
+ .xh-scope-image-cropper[data-part='crop-handle'][data-resizing] {
157
+ --xh-_image-cropper-handle-color: var(--xh-image-cropper-handle-bg-resizing, var(--xh-bg-brand));
158
+ }
159
+
160
+ .xh-scope-image-cropper[data-part='crop-handle']:focus-visible {
161
+ --xh-_image-cropper-handle-color: var(--xh-ring-focus);
162
+
163
+ outline: none;
164
+ }
165
+
166
+ /* —— 八个方位:落点 + 光标 —— */
167
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='nw'] {
168
+ top: 0;
169
+ /* stylelint-disable-next-line property-disallowed-list -- 裁切框的坐标是图片像素,落点跟着物理方向走 */
170
+ left: 0;
171
+ cursor: nwse-resize;
172
+ }
173
+
174
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='n'] {
175
+ top: 0;
176
+ /* stylelint-disable-next-line property-disallowed-list -- 同上 */
177
+ left: 50%;
178
+ cursor: ns-resize;
179
+ }
180
+
181
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='ne'] {
182
+ top: 0;
183
+ /* stylelint-disable-next-line property-disallowed-list -- 同上 */
184
+ left: 100%;
185
+ cursor: nesw-resize;
186
+ }
187
+
188
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='e'] {
189
+ top: 50%;
190
+ /* stylelint-disable-next-line property-disallowed-list -- 同上 */
191
+ left: 100%;
192
+ cursor: ew-resize;
193
+ }
194
+
195
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='se'] {
196
+ top: 100%;
197
+ /* stylelint-disable-next-line property-disallowed-list -- 同上 */
198
+ left: 100%;
199
+ cursor: nwse-resize;
200
+ }
201
+
202
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='s'] {
203
+ top: 100%;
204
+ /* stylelint-disable-next-line property-disallowed-list -- 同上 */
205
+ left: 50%;
206
+ cursor: ns-resize;
207
+ }
208
+
209
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='sw'] {
210
+ top: 100%;
211
+ /* stylelint-disable-next-line property-disallowed-list -- 同上 */
212
+ left: 0;
213
+ cursor: nesw-resize;
214
+ }
215
+
216
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='w'] {
217
+ top: 50%;
218
+ /* stylelint-disable-next-line property-disallowed-list -- 同上 */
219
+ left: 0;
220
+ cursor: ew-resize;
221
+ }
222
+
223
+ /* stylelint-disable property-disallowed-list -- 裁切框的八向位置使用图片物理坐标,内部标记必须朝对应物理方向内收 */
224
+ .xh-scope-image-cropper[data-part='crop-handle']:is([data-position='n'], [data-position='s'])::after {
225
+ left: 50%;
226
+ inline-size: var(--xh-image-cropper-handle-length, var(--xh-space-8));
227
+ block-size: var(--xh-image-cropper-handle-thickness, var(--xh-stroke-strong));
228
+ translate: -50% 0;
229
+ }
230
+
231
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='n']::after {
232
+ top: 50%;
233
+ }
234
+
235
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='s']::after {
236
+ bottom: 50%;
237
+ }
238
+
239
+ .xh-scope-image-cropper[data-part='crop-handle']:is([data-position='e'], [data-position='w'])::after {
240
+ top: 50%;
241
+ inline-size: var(--xh-image-cropper-handle-thickness, var(--xh-stroke-strong));
242
+ block-size: var(--xh-image-cropper-handle-length, var(--xh-space-8));
243
+ translate: 0 -50%;
244
+ }
245
+
246
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='e']::after {
247
+ right: 50%;
248
+ }
249
+
250
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='w']::after {
251
+ left: 50%;
252
+ }
253
+
254
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='nw'] {
255
+ border-start-start-radius: var(--xh-_image-cropper-corner-radius);
256
+ }
257
+
258
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='ne'] {
259
+ border-start-end-radius: var(--xh-_image-cropper-corner-radius);
260
+ }
261
+
262
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='sw'] {
263
+ border-end-start-radius: var(--xh-_image-cropper-corner-radius);
264
+ }
265
+
266
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='se'] {
267
+ border-end-end-radius: var(--xh-_image-cropper-corner-radius);
268
+ }
269
+
270
+ .xh-scope-image-cropper[data-part='crop-handle']:is(
271
+ [data-position='nw'],
272
+ [data-position='ne'],
273
+ [data-position='sw'],
274
+ [data-position='se']
275
+ )::after {
276
+ inline-size: calc(var(--xh-_image-cropper-handle-size) / 2);
277
+ block-size: calc(var(--xh-_image-cropper-handle-size) / 2);
278
+ border: 0 solid var(--xh-image-cropper-handle-border, var(--xh-_image-cropper-handle-color));
279
+ border-radius: inherit;
280
+ background: transparent;
281
+ outline: none;
282
+ }
283
+
284
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='nw']::after {
285
+ right: 0;
286
+ bottom: 0;
287
+ border-block-start-width: var(--xh-image-cropper-handle-thickness, var(--xh-stroke-strong));
288
+ border-inline-start-width: var(--xh-image-cropper-handle-thickness, var(--xh-stroke-strong));
289
+ }
290
+
291
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='ne']::after {
292
+ bottom: 0;
293
+ left: 0;
294
+ border-block-start-width: var(--xh-image-cropper-handle-thickness, var(--xh-stroke-strong));
295
+ border-inline-end-width: var(--xh-image-cropper-handle-thickness, var(--xh-stroke-strong));
296
+ }
297
+
298
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='sw']::after {
299
+ top: 0;
300
+ right: 0;
301
+ border-block-end-width: var(--xh-image-cropper-handle-thickness, var(--xh-stroke-strong));
302
+ border-inline-start-width: var(--xh-image-cropper-handle-thickness, var(--xh-stroke-strong));
303
+ }
304
+
305
+ .xh-scope-image-cropper[data-part='crop-handle'][data-position='se']::after {
306
+ top: 0;
307
+ left: 0;
308
+ border-block-end-width: var(--xh-image-cropper-handle-thickness, var(--xh-stroke-strong));
309
+ border-inline-end-width: var(--xh-image-cropper-handle-thickness, var(--xh-stroke-strong));
310
+ }
311
+ /* stylelint-enable property-disallowed-list */
312
+
313
+ /* 只读与禁用的光标排在八个方位之后:那八条每条都写了 cursor,特异性又完全相同,
314
+ 排在前面会被逐条盖掉,整条规则等于没写。 */
315
+ .xh-scope-image-cropper[data-part='crop-handle'][data-readonly] {
316
+ cursor: default;
317
+ }
318
+
319
+ .xh-scope-image-cropper[data-part='crop-handle'][data-disabled] {
320
+ cursor: not-allowed;
321
+ }
322
+
323
+ /* 两条控制轴用原生 range:拇指与轨道交给平台画,这里只给横向铺满与品牌色。
324
+ 不写 block-size:原生 range 的高度由 UA 与拇指尺寸定,写死会把拇指切掉一截。 */
325
+ .xh-scope-image-cropper[data-part='zoom-slider'],
326
+ .xh-scope-image-cropper[data-part='rotate-slider'] {
327
+ inline-size: var(--xh-image-cropper-slider-w, 100%);
328
+ /* 原生 range 自带左右各一段外边距,与铺满的宽度叠在一起就把这两条轴顶出容器 */
329
+ margin-inline: 0;
330
+ accent-color: var(--xh-image-cropper-slider-accent, var(--xh-bg-brand));
331
+ }
332
+
333
+ /*
334
+ * 翻转按钮是裁切器旁的独立开关钮:盒型、sm 档几何、outline 四态面、0.97 按压与粗指针命中区由家族配方
335
+ * 按连接层投影的 data-xh-action-* 给出。翻着(data-state='on')是无滑块开关的选中面:品牌淡底 12 → 悬停 20
336
+ * → 按压 28,前景 fg-on-brand-subtle;outline 的描边不换,淡底面上没有描边就与悬停面分不开。
337
+ */
338
+ .xh-scope-image-cropper[data-part='flip-trigger'] {
339
+ /* 作者塞进来的图标随档取字形尺(sm = 16px) */
340
+ --xh-icon-size: var(--xh-_action-profile-glyph-size);
341
+ }
342
+
343
+ .xh-scope-image-cropper[data-part='flip-trigger'][data-state='on'] {
344
+ --xh-action-bg-rest: var(--xh-bg-brand-subtle);
345
+ --xh-action-bg-hover: var(--xh-bg-brand-subtle-hover);
346
+ --xh-action-bg-pressed: var(--xh-bg-brand-subtle-active);
347
+ --xh-action-bg-focus-visible: var(--xh-bg-brand-subtle);
348
+ /* 翻着又被禁用:底色掺一半中性面,选中信息不丢。掺的是淡底的不透明档,墨色淡底半透明 */
349
+ --xh-action-bg-disabled: color-mix(in oklab, var(--xh-bg-brand-subtle) 50%, var(--xh-bg-subtle-opaque));
350
+ --xh-action-fg-rest: var(--xh-fg-on-brand-subtle);
351
+ --xh-action-fg-hover: var(--xh-fg-on-brand-subtle);
352
+ --xh-action-fg-pressed: var(--xh-fg-on-brand-subtle);
353
+ --xh-action-fg-focus-visible: var(--xh-fg-on-brand-subtle);
354
+ }
355
+
356
+ /* 禁用的整体压暗只做一次,落在最外层:视口、裁切框、把手各自再叠一层会越叠越黑。
357
+ 这里只用 opacity、不换前景色:框里是图像,没有文字可换。 */
358
+ .xh-scope-image-cropper[data-part='root'][data-disabled] {
359
+ opacity: var(--xh-state-disabled-opacity);
360
+ }
361
+
362
+ /* hidden-input 是 type=hidden 的原生输入,浏览器本就不渲染它,
363
+ 这里一条声明都不给:给了 display / 尺寸反而会把它拽回布局里撑出一块空白。 */
364
+
365
+ /* display 会盖掉 UA 的 [hidden]{display:none},凡是被赋了 display 的角色节点都要显式让位。
366
+ 这条必须排在全部 display 声明之后。 */
367
+ .xh-scope-image-cropper[data-part='root'][hidden],
368
+ .xh-scope-image-cropper[data-part='viewport'][hidden],
369
+ .xh-scope-image-cropper[data-part='image'][hidden],
370
+ .xh-scope-image-cropper[data-part='crop-handle'][hidden] {
371
+ display: none;
372
+ }
373
+ }