@astryx-vue/core 0.1.1 → 0.1.3

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 (223) hide show
  1. package/dist/AppShell/index.d.ts +2 -0
  2. package/dist/AppShell/index.js +2 -0
  3. package/dist/AppShell-b0PWt9Fz.js +249 -0
  4. package/dist/AspectRatio/index.d.ts +2 -0
  5. package/dist/AspectRatio/index.js +2 -0
  6. package/dist/AspectRatio-Bij7e-tq.js +40 -0
  7. package/dist/AvatarGroup/index.d.ts +1 -1
  8. package/dist/Banner/index.d.ts +1 -1
  9. package/dist/BottomSheet/index.d.ts +1 -1
  10. package/dist/ButtonGroup/index.d.ts +1 -1
  11. package/dist/Calendar/index.js +1 -1
  12. package/dist/{Calendar-BEyrkUtr.js → Calendar-CYhGDT6f.js} +1 -1
  13. package/dist/Chat/index.js +1 -1
  14. package/dist/{Chat-CO3mCs9A.js → Chat-C1aWl5V3.js} +1 -1
  15. package/dist/CheckboxInput/index.d.ts +1 -1
  16. package/dist/CheckboxInput/index.js +1 -1
  17. package/dist/{CheckboxInput-C86o3XoG.js → CheckboxInput-CMsEE1_4.js} +4 -2
  18. package/dist/CheckboxList/index.d.ts +1 -1
  19. package/dist/CheckboxList/index.js +1 -1
  20. package/dist/{CheckboxList-BL2sDOWK.js → CheckboxList-EsIEXjK_.js} +2 -2
  21. package/dist/Citation/index.js +1 -1
  22. package/dist/{Citation-BqwJvw7o.js → Citation-C1X0Rde8.js} +1 -1
  23. package/dist/ClickableCard/index.d.ts +2 -0
  24. package/dist/ClickableCard/index.js +2 -0
  25. package/dist/ClickableCard-Bhds4RRe.js +112 -0
  26. package/dist/Collapsible/index.d.ts +2 -2
  27. package/dist/Collapsible/index.js +2 -2
  28. package/dist/Collapsible-BS9ctCQV.js +192 -0
  29. package/dist/CommandPalette/index.d.ts +2 -0
  30. package/dist/CommandPalette/index.js +2 -0
  31. package/dist/CommandPalette-u5h_E05P.js +489 -0
  32. package/dist/ComplexSelector/index.d.ts +2 -0
  33. package/dist/ComplexSelector/index.js +2 -0
  34. package/dist/ComplexSelector-BHmGWml0.js +293 -0
  35. package/dist/ContextMenu/index.d.ts +1 -1
  36. package/dist/DateInput/index.d.ts +1 -1
  37. package/dist/DateInput/index.js +1 -1
  38. package/dist/{DateInput-BOIb0zAp.js → DateInput-D2ErjXYO.js} +2 -2
  39. package/dist/DateRangeInput/index.d.ts +1 -1
  40. package/dist/DateRangeInput/index.js +1 -1
  41. package/dist/{DateRangeInput-DLcbgUBi.js → DateRangeInput-fmQlr_A7.js} +3 -3
  42. package/dist/DateTimeInput/index.d.ts +1 -1
  43. package/dist/DateTimeInput/index.js +1 -1
  44. package/dist/{DateTimeInput-RitYX_Yx.js → DateTimeInput-Bs1JmcIp.js} +4 -4
  45. package/dist/Field/index.js +2 -2
  46. package/dist/{Field-VlTBsIEo.js → Field-8zRxzDHE.js} +11 -3
  47. package/dist/{FieldLabel-B1NRyQlS.js → FieldLabel-DmmJyX7w.js} +6 -1
  48. package/dist/FileInput/index.d.ts +1 -1
  49. package/dist/FileInput/index.js +1 -1
  50. package/dist/{FileInput-CYvEV503.js → FileInput-CmAfOpkA.js} +2 -2
  51. package/dist/FormLayout/index.d.ts +2 -0
  52. package/dist/FormLayout/index.js +2 -0
  53. package/dist/FormLayout-D47FjiOq.js +40 -0
  54. package/dist/HoverCard/index.d.ts +1 -1
  55. package/dist/Layout/index.d.ts +2 -0
  56. package/dist/Layout/index.js +3 -0
  57. package/dist/Layout-Bed3kP0M.js +56 -0
  58. package/dist/LayoutPanel-C34uOq3e.js +358 -0
  59. package/dist/List/index.d.ts +1 -1
  60. package/dist/Markdown/index.d.ts +1 -1
  61. package/dist/Markdown/index.js +1 -1
  62. package/dist/{Markdown-Dnlp8cVx.js → Markdown-CwtLr3f_.js} +1 -1
  63. package/dist/MetadataList/index.js +1 -1
  64. package/dist/{MetadataList-DIsqS1Qb.js → MetadataList-DlXQTLog.js} +1 -1
  65. package/dist/MobileNav/index.d.ts +1 -1
  66. package/dist/MobileNav/index.js +1 -1
  67. package/dist/{MobileNavToggle-aUZiDwHm.js → MobileNavToggle-CgQamG6E.js} +19 -12
  68. package/dist/MoreMenu/index.d.ts +1 -1
  69. package/dist/MultiSelector/index.d.ts +1 -1
  70. package/dist/MultiSelector/index.js +1 -1
  71. package/dist/{MultiSelector-Bh8or2S6.js → MultiSelector-DT8ZccMI.js} +3 -3
  72. package/dist/NavItem/index.d.ts +1 -1
  73. package/dist/NavMenu/index.d.ts +1 -1
  74. package/dist/NumberInput/index.d.ts +1 -1
  75. package/dist/NumberInput/index.js +1 -1
  76. package/dist/{NumberInput-C3S-4dIu.js → NumberInput-DspJO6z6.js} +1 -1
  77. package/dist/OverflowList/index.d.ts +1 -1
  78. package/dist/OverflowList/index.js +1 -1
  79. package/dist/{OverflowList-Kr4iJrNV.js → OverflowList-zXg3g6fy.js} +1 -1
  80. package/dist/Overlay/index.d.ts +1 -1
  81. package/dist/Pagination/index.js +1 -1
  82. package/dist/{Pagination-BRStpeSB.js → Pagination-DXfgMUKJ.js} +2 -2
  83. package/dist/Popover/index.d.ts +2 -1
  84. package/dist/Radio/index.d.ts +1 -1
  85. package/dist/Radio/index.js +1 -1
  86. package/dist/{RadioGroup-DS6oTV_j.js → RadioGroup-BqjdSCfJ.js} +1 -1
  87. package/dist/RadioList/index.d.ts +1 -1
  88. package/dist/RadioList/index.js +1 -1
  89. package/dist/{RadioList-pwr93I-z.js → RadioList-DI8ujXcT.js} +1 -1
  90. package/dist/Resizable/index.d.ts +2 -0
  91. package/dist/Resizable/index.js +2 -0
  92. package/dist/Resizable-BuGKvU9I.js +261 -0
  93. package/dist/ScrollableArea/index.d.ts +2 -0
  94. package/dist/ScrollableArea/index.js +2 -0
  95. package/dist/ScrollableArea-DQDYjnxO.js +78 -0
  96. package/dist/Section/index.d.ts +2 -0
  97. package/dist/Section/index.js +2 -0
  98. package/dist/Section-C48Wqfc7.js +68 -0
  99. package/dist/SelectableCard/index.d.ts +2 -0
  100. package/dist/SelectableCard/index.js +2 -0
  101. package/dist/SelectableCard-Bj5s_tIN.js +108 -0
  102. package/dist/Selector/index.d.ts +1 -1
  103. package/dist/Selector/index.js +1 -1
  104. package/dist/{Selector-DvEUIVEC.js → Selector-DlZpQh42.js} +1 -1
  105. package/dist/SideNav/index.d.ts +1 -1
  106. package/dist/SideNav/index.js +2 -1
  107. package/dist/{SideNav-B7LX4RcP.js → SideNav-Cdrigq2A.js} +48 -26
  108. package/dist/Slider/index.js +1 -1
  109. package/dist/{Slider-DTnWxtnb.js → Slider-D8h_RKcF.js} +1 -1
  110. package/dist/Stepper/index.d.ts +2 -0
  111. package/dist/Stepper/index.js +2 -0
  112. package/dist/Stepper-DxmLfh8O.js +423 -0
  113. package/dist/Switch/index.d.ts +1 -1
  114. package/dist/Switch/index.js +1 -1
  115. package/dist/{Switch-CNdnr5TP.js → Switch-SesQzPGZ.js} +4 -2
  116. package/dist/TabList/index.d.ts +2 -2
  117. package/dist/TabList/index.js +2 -2
  118. package/dist/TabList-C411uNQU.js +380 -0
  119. package/dist/Table/index.d.ts +2 -1
  120. package/dist/Table/index.js +1 -1
  121. package/dist/{Table-D5zWaITo.js → Table-7qRmlIQd.js} +5 -5
  122. package/dist/TextArea/index.d.ts +1 -1
  123. package/dist/TextArea/index.js +1 -1
  124. package/dist/{TextArea-BL0NuB99.js → TextArea-Cv9UVbzS.js} +5 -3
  125. package/dist/TextInput/index.d.ts +1 -1
  126. package/dist/TextInput/index.js +1 -1
  127. package/dist/{TextInput-B0IKC7g5.js → TextInput-BasnjVvy.js} +5 -3
  128. package/dist/Thumbnail/index.js +1 -1
  129. package/dist/{Thumbnail-DMOgWncm.js → Thumbnail-BWVzLLyI.js} +1 -1
  130. package/dist/{TimeField-DeQ1ukHl.js → TimeField-l3QzU6vC.js} +1 -1
  131. package/dist/TimeInput/index.d.ts +1 -1
  132. package/dist/TimeInput/index.js +1 -1
  133. package/dist/{TimeInput-jb1nLqZk.js → TimeInput-OkgX-xbQ.js} +2 -2
  134. package/dist/Timestamp/index.d.ts +1 -1
  135. package/dist/Timestamp/index.js +1 -1
  136. package/dist/{Timestamp-DrWwVQBL.js → Timestamp-DUoP9ari.js} +1 -1
  137. package/dist/ToggleButton/index.d.ts +1 -1
  138. package/dist/Token/index.d.ts +1 -1
  139. package/dist/Token/index.js +1 -1
  140. package/dist/{Token-CV2J94bn.js → Token-C4KD0fZD.js} +1 -1
  141. package/dist/Tokenizer/index.js +1 -1
  142. package/dist/{Tokenizer-DF9r4hTW.js → Tokenizer-BA8sTMPZ.js} +3 -3
  143. package/dist/Toolbar/index.d.ts +1 -1
  144. package/dist/Tooltip/index.d.ts +1 -1
  145. package/dist/TopNav/index.d.ts +1 -1
  146. package/dist/TopNav/index.js +1 -1
  147. package/dist/{TopNav-BH_s3uap.js → TopNav-CZokS7E_.js} +57 -31
  148. package/dist/TreeList/index.js +1 -1
  149. package/dist/{TreeList-D9cR-w7r.js → TreeList-CIbAGOMf.js} +1 -1
  150. package/dist/Typeahead/index.js +1 -1
  151. package/dist/{Typeahead-s4DC1Qem.js → Typeahead-DIw-K4aa.js} +3 -3
  152. package/dist/composables/index.d.ts +3 -2
  153. package/dist/composables/index.js +5 -2
  154. package/dist/composables-CVfjp9h4.js +502 -0
  155. package/dist/context-BjNya0v8.js +19 -0
  156. package/dist/context-Cfjh8te1.js +29 -0
  157. package/dist/{context-BshXcNYX.js → context-D6ECRdc5.js} +84 -0
  158. package/dist/index-1uRMrk63.d.ts +54 -0
  159. package/dist/{index-CsJpQElv.d.ts → index-2u4l3wq8.d.ts} +1 -1
  160. package/dist/{index-BlWLperN.d.ts → index-4FM5lQdV.d.ts} +1 -1
  161. package/dist/index-Be1czg3M.d.ts +167 -0
  162. package/dist/{index-Dbmgcm8a.d.ts → index-BeR-1LgF.d.ts} +2 -0
  163. package/dist/index-BrJzFA5X.d.ts +38 -0
  164. package/dist/{index-BDZCJ9ri.d.ts → index-BuubzuE8.d.ts} +2 -2
  165. package/dist/index-By2mSzUA.d.ts +67 -0
  166. package/dist/{index-BkIgRYGz.d.ts → index-C5p2NeCr.d.ts} +2 -2
  167. package/dist/{index-AkMWQ97a.d.ts → index-C6RecznD.d.ts} +1 -1
  168. package/dist/{index-BSRk8MFK.d.ts → index-C8wDPDcP.d.ts} +1 -1
  169. package/dist/index-CDdRQQF3.d.ts +170 -0
  170. package/dist/index-COqjznX0.d.ts +47 -0
  171. package/dist/{index-g03bmR4K.d.ts → index-CT8KEpec.d.ts} +2 -2
  172. package/dist/{index-Bc0dgVM5.d.ts → index-CTolyeii.d.ts} +4 -4
  173. package/dist/index-CVn0GBdB.d.ts +115 -0
  174. package/dist/index-CX97hlld.d.ts +158 -0
  175. package/dist/index-CjtAH60j.d.ts +38 -0
  176. package/dist/{index-5R_pi3eT.d.ts → index-D-ZuubCK.d.ts} +3 -3
  177. package/dist/index-DA52oIdw.d.ts +171 -0
  178. package/dist/{index-D3V7yRUP.d.ts → index-DGNqi2za.d.ts} +1 -1
  179. package/dist/{index-CCA4R0Mf.d.ts → index-DT9S92sh.d.ts} +31 -6
  180. package/dist/{index-CR6sUmRT.d.ts → index-DXSs3rwa.d.ts} +3 -107
  181. package/dist/{index-CNcQmDrK.d.ts → index-DYChvBOM.d.ts} +42 -0
  182. package/dist/{index-CQ9F1f_F.d.ts → index-Df2YvC8o.d.ts} +297 -125
  183. package/dist/{index--dh0s8Li.d.ts → index-DfgHJE7H.d.ts} +1 -1
  184. package/dist/{index-BnNh5Iml.d.ts → index-SMh42NI8.d.ts} +99 -2
  185. package/dist/{index-12ObcW99.d.ts → index-ZJyk8RtQ.d.ts} +1 -1
  186. package/dist/{index-Q4gqBSIZ.d.ts → index-fa72tWIU.d.ts} +1 -1
  187. package/dist/{index-BhYFxnjV.d.ts → index-kaKBOZSU.d.ts} +2 -2
  188. package/dist/index-nKlTsNfV.d.ts +42 -0
  189. package/dist/index.d.ts +75 -63
  190. package/dist/index.js +108 -89
  191. package/dist/locale/index.d.ts +1 -1
  192. package/dist/locale/index.js +1 -1
  193. package/dist/size-BuTzpgnR.d.ts +14 -0
  194. package/dist/size-xcIqExkS.js +79 -0
  195. package/dist/{index-Bovw9_8d.d.ts → types-Db3Owy8Q.d.ts} +1 -36
  196. package/dist/types-JktRxujg.d.ts +107 -0
  197. package/dist/useAppShellMobile-DTsyuAJ4.js +19 -0
  198. package/dist/useClickableContainer-DyNpnSEa.js +112 -0
  199. package/dist/useResizable-CeESZS1v.d.ts +72 -0
  200. package/dist/useScrollableArea-DDk_CluT.js +172 -0
  201. package/package.json +49 -1
  202. package/styles/app-shell.css +151 -0
  203. package/styles/aspect-ratio.css +49 -0
  204. package/styles/card.css +5 -1
  205. package/styles/clickable-card.css +101 -0
  206. package/styles/collapsible.css +37 -0
  207. package/styles/command-palette.css +183 -0
  208. package/styles/complex-selector.css +114 -0
  209. package/styles/field.css +12 -0
  210. package/styles/form-layout.css +31 -0
  211. package/styles/heading.css +19 -17
  212. package/styles/layout.css +280 -0
  213. package/styles/resize-handle.css +128 -0
  214. package/styles/scrollable-area.css +50 -0
  215. package/styles/section.css +60 -0
  216. package/styles/side-nav.css +26 -0
  217. package/styles/stepper.css +357 -0
  218. package/styles/tab-menu.css +91 -0
  219. package/styles.css +12 -0
  220. package/dist/Collapsible-BYg9soTk.js +0 -102
  221. package/dist/TabList-LV1U4ZD6.js +0 -184
  222. package/dist/composables-Dq9RS33w.js +0 -111
  223. package/dist/index-TnaIHsCS.d.ts +0 -87
@@ -0,0 +1,112 @@
1
+ //#region src/composables/useClickableContainer.ts
2
+ /**
3
+ * 对应原版 Astryx 的 `hooks/useClickableContainer`。
4
+ *
5
+ * 让整块容器可点,同时把点在嵌套按钮、链接、输入框上的点击留给那些控件自己。
6
+ * ClickableCard 和 SelectableCard 都走这里,避免两套“点到谁算谁”的判断。
7
+ */
8
+ const INTERACTIVE_SELECTORS = [
9
+ "button",
10
+ "a",
11
+ "input",
12
+ "select",
13
+ "textarea",
14
+ "[role=\"button\"]",
15
+ "[role=\"link\"]",
16
+ "[role=\"checkbox\"]",
17
+ "[role=\"radio\"]",
18
+ "[role=\"switch\"]",
19
+ "[role=\"tab\"]",
20
+ "[role=\"menuitem\"]",
21
+ "[role=\"option\"]",
22
+ "[role=\"combobox\"]",
23
+ "[role=\"listbox\"]",
24
+ "[role=\"slider\"]",
25
+ "[role=\"spinbutton\"]",
26
+ "[data-pressable-container]"
27
+ ].join(",");
28
+ const NON_INTERACTIVE_SELECTORS = "[aria-readonly=\"true\"]";
29
+ function hasInteractiveAncestor(element, root) {
30
+ let current = element;
31
+ while (current != null && current !== root && current !== document.body) {
32
+ if (current.matches(INTERACTIVE_SELECTORS) && !current.matches(NON_INTERACTIVE_SELECTORS)) return true;
33
+ current = current.parentElement;
34
+ }
35
+ return false;
36
+ }
37
+ function hasTextSelection(node) {
38
+ if (typeof document === "undefined" || document.getSelection == null) return false;
39
+ const selection = document.getSelection();
40
+ if (selection == null || selection.isCollapsed) return false;
41
+ return node.contains(selection.anchorNode);
42
+ }
43
+ function openInNewTab(href) {
44
+ window.open(href, "_blank", "noopener");
45
+ }
46
+ /**
47
+ * 把容器的 click / mouseup 交给调用方绑到根元素上。
48
+ * 组件挂载后会给容器加上 `data-pressable-container`,嵌套的可点容器因此不会互相抢走点击。
49
+ */
50
+ function useClickableContainer(options) {
51
+ function markContainer() {
52
+ const container = options.containerRef.value;
53
+ if (container != null) container.dataset.pressableContainer = "true";
54
+ }
55
+ function onClick(event) {
56
+ markContainer();
57
+ if (options.disabled) return;
58
+ const container = options.containerRef.value;
59
+ if (container == null) return;
60
+ if (hasTextSelection(container)) return;
61
+ const target = event.target;
62
+ if (!(target instanceof Element)) return;
63
+ if (target !== event.currentTarget && hasInteractiveAncestor(target, container)) return;
64
+ options.onClick?.(event);
65
+ if (event.defaultPrevented) return;
66
+ const href = options.href;
67
+ if (href != null && href !== "") {
68
+ if (options.target === "_blank" || event.metaKey || event.ctrlKey) {
69
+ openInNewTab(href);
70
+ return;
71
+ }
72
+ const interactive = options.interactiveRef?.value;
73
+ if (interactive != null) {
74
+ interactive.click();
75
+ return;
76
+ }
77
+ window.location.assign(href);
78
+ return;
79
+ }
80
+ if (options.onClick == null) {
81
+ const interactive = options.interactiveRef?.value;
82
+ if (interactive != null) {
83
+ interactive.dispatchEvent(new MouseEvent("click", {
84
+ bubbles: true,
85
+ cancelable: true,
86
+ button: event.button,
87
+ ctrlKey: event.ctrlKey,
88
+ metaKey: event.metaKey,
89
+ shiftKey: event.shiftKey,
90
+ altKey: event.altKey
91
+ }));
92
+ event.stopPropagation();
93
+ }
94
+ }
95
+ }
96
+ function onMouseUp(event) {
97
+ if (options.disabled) return;
98
+ const href = options.href;
99
+ if (href == null || href === "" || event.button !== 1) return;
100
+ const container = options.containerRef.value;
101
+ const target = event.target;
102
+ if (container == null || !(target instanceof Element)) return;
103
+ if (target !== event.currentTarget && hasInteractiveAncestor(target, container)) return;
104
+ openInNewTab(href);
105
+ }
106
+ return {
107
+ onClick,
108
+ onMouseUp
109
+ };
110
+ }
111
+ //#endregion
112
+ export { useClickableContainer as n, INTERACTIVE_SELECTORS as t };
@@ -0,0 +1,72 @@
1
+ import { n as PixelWidth } from "./types-JktRxujg.js";
2
+ import { Ref } from "vue";
3
+ //#region src/composables/useResizable.d.ts
4
+ type ResizableDirection = 'horizontal' | 'vertical';
5
+ interface ResizablePercentSize {
6
+ type: 'percent';
7
+ value: number;
8
+ min?: PixelWidth;
9
+ max?: PixelWidth;
10
+ }
11
+ type ResizableSize = number | `${number}px` | `${number}%` | PixelWidth | ResizablePercentSize;
12
+ interface ResizableRegionConfig {
13
+ defaultSize?: ResizableSize | string;
14
+ minSize?: ResizableSize | string;
15
+ maxSize?: ResizableSize | string;
16
+ collapsible?: boolean;
17
+ collapsedSize?: number;
18
+ snaps?: number[];
19
+ /** Cascade priority. A lower number gives up space first when the shared container is narrower than the regions. */
20
+ shrinkOrder?: number;
21
+ }
22
+ interface UseResizableSingleOptions extends ResizableRegionConfig {
23
+ containerRef?: Ref<HTMLElement | null>;
24
+ direction?: ResizableDirection;
25
+ autoSaveId?: string;
26
+ defaultIsCollapsed?: boolean;
27
+ isCollapsed?: boolean;
28
+ onSizeChange?: (size: number) => void;
29
+ onCollapseChange?: (isCollapsed: boolean) => void;
30
+ }
31
+ interface UseResizableMultiConfig {
32
+ direction?: ResizableDirection;
33
+ containerRef?: Ref<HTMLElement | null>;
34
+ regions: Record<string, ResizableRegionConfig>;
35
+ autoSaveId?: string;
36
+ }
37
+ interface ResizableProps {
38
+ _size: number;
39
+ _isCollapsed: boolean;
40
+ _onResizeStart: () => void;
41
+ _onResizeMove: (delta: number) => void;
42
+ _onResizeEnd: () => void;
43
+ _onResizeCancel?: () => void;
44
+ _minSizePx: number;
45
+ _maxSizePx: number;
46
+ _snaps: number[];
47
+ _collapsedSize: number;
48
+ _collapsible: boolean;
49
+ _direction?: ResizableDirection;
50
+ _isResizableProps: true;
51
+ }
52
+ interface ResizableRegion {
53
+ size: number;
54
+ isCollapsed: boolean;
55
+ collapse: () => void;
56
+ expand: () => void;
57
+ resize: (size: number) => void;
58
+ props: ResizableProps;
59
+ }
60
+ declare function percent(value: number, options: {
61
+ min: PixelWidth;
62
+ max?: never;
63
+ } | {
64
+ min?: never;
65
+ max: PixelWidth;
66
+ }): ResizablePercentSize;
67
+ declare function useResizable(options: UseResizableMultiConfig): Record<string, ResizableRegion>;
68
+ declare function useResizable(options: UseResizableSingleOptions): ResizableRegion;
69
+ type UseResizableOptions = UseResizableSingleOptions | UseResizableMultiConfig;
70
+ type ResizableState = ResizableRegion;
71
+ //#endregion
72
+ export { ResizableRegionConfig as a, UseResizableMultiConfig as c, percent as d, useResizable as f, ResizableRegion as i, UseResizableOptions as l, ResizablePercentSize as n, ResizableSize as o, ResizableProps as r, ResizableState as s, ResizableDirection as t, UseResizableSingleOptions as u };
@@ -0,0 +1,172 @@
1
+ import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
2
+ //#region src/composables/useScrollableArea.ts
3
+ const TOLERANCE = 1;
4
+ const idleAxis = () => ({
5
+ isScrollable: false,
6
+ atStart: true,
7
+ atEnd: true
8
+ });
9
+ function mappingFor(element) {
10
+ const style = getComputedStyle(element);
11
+ const mode = style.writingMode.toLowerCase();
12
+ const vertical = mode.startsWith("vertical") || mode.startsWith("sideways");
13
+ const rtl = style.direction === "rtl";
14
+ if (!vertical) return {
15
+ inline: "x",
16
+ block: "y",
17
+ inlineReversed: rtl,
18
+ blockReversed: false
19
+ };
20
+ return {
21
+ inline: "y",
22
+ block: "x",
23
+ inlineReversed: mode === "sideways-lr" ? !rtl : rtl,
24
+ blockReversed: mode.endsWith("-rl")
25
+ };
26
+ }
27
+ function extent(element, axis) {
28
+ if (axis === "x") return {
29
+ client: element.clientWidth,
30
+ content: element.scrollWidth,
31
+ offset: element.scrollLeft
32
+ };
33
+ return {
34
+ client: element.clientHeight,
35
+ content: element.scrollHeight,
36
+ offset: element.scrollTop
37
+ };
38
+ }
39
+ function useScrollableArea(options) {
40
+ const viewport = ref(null);
41
+ const content = ref(null);
42
+ const inline = ref(idleAxis());
43
+ const block = ref(idleAxis());
44
+ const overflowInline = ref(false);
45
+ const overflowBlock = ref(false);
46
+ const mapping = ref({
47
+ inline: "x",
48
+ block: "y",
49
+ inlineReversed: false,
50
+ blockReversed: false
51
+ });
52
+ let observer;
53
+ const axis = computed(() => options.axis ?? "block");
54
+ const overscroll = computed(() => options.overscroll ?? "allow");
55
+ const stickyContainment = computed(() => options.stickyContainment ?? "whenScrollable");
56
+ function requested(name) {
57
+ return axis.value === name || axis.value === "both";
58
+ }
59
+ function sameAxis(current, next) {
60
+ return current.isScrollable === next.isScrollable && current.atStart === next.atStart && current.atEnd === next.atEnd;
61
+ }
62
+ function measure() {
63
+ const element = viewport.value;
64
+ if (element == null) return;
65
+ const nextMapping = mappingFor(element);
66
+ const read = (name, reversed) => {
67
+ const box = extent(element, nextMapping[name]);
68
+ const overflowing = box.content > box.client + TOLERANCE;
69
+ const max = Math.max(0, box.content - box.client);
70
+ const offset = reversed ? max - Math.abs(box.offset) : Math.abs(box.offset);
71
+ const active = requested(name) && overflowing;
72
+ return {
73
+ overflowing,
74
+ state: {
75
+ isScrollable: active,
76
+ atStart: !active || offset <= TOLERANCE,
77
+ atEnd: !active || offset >= max - TOLERANCE
78
+ }
79
+ };
80
+ };
81
+ const inlineRead = read("inline", nextMapping.inlineReversed);
82
+ const blockRead = read("block", nextMapping.blockReversed);
83
+ const nextInline = requested("inline") ? inlineRead.state : idleAxis();
84
+ const nextBlock = requested("block") ? blockRead.state : idleAxis();
85
+ if (mapping.value.inline === nextMapping.inline && mapping.value.block === nextMapping.block && mapping.value.inlineReversed === nextMapping.inlineReversed && mapping.value.blockReversed === nextMapping.blockReversed && overflowInline.value === inlineRead.overflowing && overflowBlock.value === blockRead.overflowing && sameAxis(inline.value, nextInline) && sameAxis(block.value, nextBlock)) return;
86
+ mapping.value = nextMapping;
87
+ overflowInline.value = inlineRead.overflowing;
88
+ overflowBlock.value = blockRead.overflowing;
89
+ inline.value = nextInline;
90
+ block.value = nextBlock;
91
+ }
92
+ let queued = false;
93
+ function queueMeasure() {
94
+ if (queued) return;
95
+ queued = true;
96
+ queueMicrotask(() => {
97
+ queued = false;
98
+ measure();
99
+ });
100
+ }
101
+ function bind(element) {
102
+ const node = element instanceof HTMLElement ? element : null;
103
+ if (viewport.value === node) return;
104
+ viewport.value?.removeEventListener("scroll", measure);
105
+ observer?.disconnect();
106
+ observer = void 0;
107
+ viewport.value = node;
108
+ if (node == null) return;
109
+ node.addEventListener("scroll", measure, { passive: true });
110
+ if (typeof ResizeObserver !== "undefined") {
111
+ observer = new ResizeObserver(() => queueMeasure());
112
+ observer.observe(node);
113
+ if (content.value) observer.observe(content.value);
114
+ }
115
+ queueMeasure();
116
+ }
117
+ watch(content, (element) => {
118
+ if (element && observer) observer.observe(element);
119
+ queueMeasure();
120
+ });
121
+ watch([
122
+ axis,
123
+ overscroll,
124
+ stickyContainment
125
+ ], queueMeasure);
126
+ onMounted(queueMeasure);
127
+ onBeforeUnmount(() => {
128
+ viewport.value?.removeEventListener("scroll", measure);
129
+ observer?.disconnect();
130
+ });
131
+ const viewportStyle = computed(() => {
132
+ const map = mapping.value;
133
+ const requestedX = requested("inline") && map.inline === "x" || requested("block") && map.block === "x";
134
+ const requestedY = requested("inline") && map.inline === "y" || requested("block") && map.block === "y";
135
+ const overflowingX = overflowInline.value && map.inline === "x" || overflowBlock.value && map.block === "x";
136
+ const overflowingY = overflowInline.value && map.inline === "y" || overflowBlock.value && map.block === "y";
137
+ const contains = overflowingX || overflowingY || stickyContainment.value === "always";
138
+ const scrollsX = stickyContainment.value === "always" ? requestedX : overflowingX;
139
+ const scrollsY = stickyContainment.value === "always" ? requestedY : overflowingY;
140
+ const style = {
141
+ overflowX: contains ? scrollsX ? "auto" : "hidden" : "clip",
142
+ overflowY: contains ? scrollsY ? "auto" : "hidden" : "clip"
143
+ };
144
+ if (requested("inline")) style[map.inline === "x" ? "overscrollBehaviorX" : "overscrollBehaviorY"] = overscroll.value === "contain" && inline.value.isScrollable ? "contain" : "auto";
145
+ if (requested("block")) style[map.block === "x" ? "overscrollBehaviorX" : "overscrollBehaviorY"] = overscroll.value === "contain" && block.value.isScrollable ? "contain" : "auto";
146
+ return style;
147
+ });
148
+ const scrollable = computed(() => inline.value.isScrollable || block.value.isScrollable);
149
+ return {
150
+ viewport: bind,
151
+ content,
152
+ viewportAttrs: computed(() => ({
153
+ "role": options.role ?? "group",
154
+ "aria-label": options.label,
155
+ "tabindex": scrollable.value ? 0 : void 0,
156
+ "data-scroll-axis": axis.value,
157
+ "data-scrollable-inline": inline.value.isScrollable ? "true" : void 0,
158
+ "data-scrollable-block": block.value.isScrollable ? "true" : void 0,
159
+ "data-scroll-inline-start": inline.value.atStart ? "true" : void 0,
160
+ "data-scroll-inline-end": inline.value.atEnd ? "true" : void 0,
161
+ "data-scroll-block-start": block.value.atStart ? "true" : void 0,
162
+ "data-scroll-block-end": block.value.atEnd ? "true" : void 0
163
+ })),
164
+ viewportStyle,
165
+ state: computed(() => ({
166
+ inline: inline.value,
167
+ block: block.value
168
+ }))
169
+ };
170
+ }
171
+ //#endregion
172
+ export { useScrollableArea as t };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@astryx-vue/core",
3
3
  "type": "module",
4
- "version": "0.1.1",
4
+ "version": "0.1.3",
5
5
  "description": "Vue components for the unofficial astryx-vue community project.",
6
6
  "author": "ShenQingchuan",
7
7
  "license": "MIT",
@@ -28,6 +28,14 @@
28
28
  "types": "./dist/index.d.ts",
29
29
  "import": "./dist/index.js"
30
30
  },
31
+ "./AppShell": {
32
+ "types": "./dist/AppShell/index.d.ts",
33
+ "import": "./dist/AppShell/index.js"
34
+ },
35
+ "./AspectRatio": {
36
+ "types": "./dist/AspectRatio/index.d.ts",
37
+ "import": "./dist/AspectRatio/index.js"
38
+ },
31
39
  "./Avatar": {
32
40
  "types": "./dist/Avatar/index.d.ts",
33
41
  "import": "./dist/Avatar/index.js"
@@ -40,6 +48,18 @@
40
48
  "types": "./dist/CheckboxList/index.d.ts",
41
49
  "import": "./dist/CheckboxList/index.js"
42
50
  },
51
+ "./ClickableCard": {
52
+ "types": "./dist/ClickableCard/index.d.ts",
53
+ "import": "./dist/ClickableCard/index.js"
54
+ },
55
+ "./CommandPalette": {
56
+ "types": "./dist/CommandPalette/index.d.ts",
57
+ "import": "./dist/CommandPalette/index.js"
58
+ },
59
+ "./ComplexSelector": {
60
+ "types": "./dist/ComplexSelector/index.d.ts",
61
+ "import": "./dist/ComplexSelector/index.js"
62
+ },
43
63
  "./DateRangeInput": {
44
64
  "types": "./dist/DateRangeInput/index.d.ts",
45
65
  "import": "./dist/DateRangeInput/index.js"
@@ -56,6 +76,14 @@
56
76
  "types": "./dist/FileInput/index.d.ts",
57
77
  "import": "./dist/FileInput/index.js"
58
78
  },
79
+ "./FormLayout": {
80
+ "types": "./dist/FormLayout/index.d.ts",
81
+ "import": "./dist/FormLayout/index.js"
82
+ },
83
+ "./Layout": {
84
+ "types": "./dist/Layout/index.d.ts",
85
+ "import": "./dist/Layout/index.js"
86
+ },
59
87
  "./MetadataList": {
60
88
  "types": "./dist/MetadataList/index.d.ts",
61
89
  "import": "./dist/MetadataList/index.js"
@@ -64,6 +92,22 @@
64
92
  "types": "./dist/RadioList/index.d.ts",
65
93
  "import": "./dist/RadioList/index.js"
66
94
  },
95
+ "./Resizable": {
96
+ "types": "./dist/Resizable/index.d.ts",
97
+ "import": "./dist/Resizable/index.js"
98
+ },
99
+ "./ScrollableArea": {
100
+ "types": "./dist/ScrollableArea/index.d.ts",
101
+ "import": "./dist/ScrollableArea/index.js"
102
+ },
103
+ "./Section": {
104
+ "types": "./dist/Section/index.d.ts",
105
+ "import": "./dist/Section/index.js"
106
+ },
107
+ "./SelectableCard": {
108
+ "types": "./dist/SelectableCard/index.d.ts",
109
+ "import": "./dist/SelectableCard/index.js"
110
+ },
67
111
  "./StatusDot": {
68
112
  "types": "./dist/StatusDot/index.d.ts",
69
113
  "import": "./dist/StatusDot/index.js"
@@ -116,6 +160,10 @@
116
160
  "types": "./dist/Radio/index.d.ts",
117
161
  "import": "./dist/Radio/index.js"
118
162
  },
163
+ "./Stepper": {
164
+ "types": "./dist/Stepper/index.d.ts",
165
+ "import": "./dist/Stepper/index.js"
166
+ },
119
167
  "./Table": {
120
168
  "types": "./dist/Table/index.d.ts",
121
169
  "import": "./dist/Table/index.js"
@@ -0,0 +1,151 @@
1
+ @layer astryx.reset, astryx.tokens, astryx.base, astryx.components, astryx.overrides;
2
+
3
+ @layer astryx.components {
4
+ .astryx-app-shell {
5
+ display: flex;
6
+ flex-direction: column;
7
+ position: relative;
8
+ overflow: clip;
9
+ min-height: 0;
10
+ }
11
+
12
+ .astryx-app-shell[data-variant='wash'],
13
+ .astryx-app-shell[data-variant='elevated'] {
14
+ background-color: var(--astryx-color-background-body, #f1f1f1);
15
+ }
16
+
17
+ .astryx-app-shell[data-variant='surface'],
18
+ .astryx-app-shell[data-variant='section'] {
19
+ background-color: var(--astryx-color-background-surface, #fff);
20
+ }
21
+
22
+ .astryx-app-shell[data-height='fill'] {
23
+ height: 100dvh;
24
+ }
25
+
26
+ .astryx-app-shell[data-height='auto'] {
27
+ min-height: 100dvh;
28
+ }
29
+
30
+ .astryx-app-shell > .astryx-layout {
31
+ flex: 1;
32
+ min-height: 0;
33
+ }
34
+
35
+ .astryx-app-shell__skip {
36
+ position: absolute;
37
+ width: 1px;
38
+ height: 1px;
39
+ margin: -1px;
40
+ padding: 0;
41
+ overflow: hidden;
42
+ border: 0;
43
+ clip-path: inset(50%);
44
+ white-space: nowrap;
45
+ background-color: var(--astryx-color-background-surface, #fff);
46
+ color: var(--astryx-color-text-accent, #262626);
47
+ font-weight: var(--astryx-font-weight-semibold, 600);
48
+ text-decoration: none;
49
+ z-index: 9999;
50
+ }
51
+
52
+ .astryx-app-shell__skip:focus {
53
+ position: fixed;
54
+ top: var(--astryx-spacing-2, 8px);
55
+ inset-inline-start: var(--astryx-spacing-2, 8px);
56
+ width: auto;
57
+ height: auto;
58
+ margin: 0;
59
+ padding-block: var(--astryx-spacing-2, 8px);
60
+ padding-inline: var(--astryx-spacing-4, 16px);
61
+ overflow: visible;
62
+ clip-path: none;
63
+ white-space: normal;
64
+ outline: var(--astryx-focus-outline-width, 2px) var(--astryx-focus-outline-style, solid) var(--astryx-focus-outline-color, currentcolor);
65
+ outline-offset: var(--astryx-focus-outline-offset, 3px);
66
+ }
67
+
68
+ .astryx-app-shell__header[data-variant='wash'],
69
+ .astryx-app-shell__header[data-variant='elevated'],
70
+ .astryx-app-shell__sidenav[data-variant='wash'],
71
+ .astryx-app-shell__sidenav[data-variant='elevated'] {
72
+ background-color: var(--astryx-color-background-body, #f1f1f1);
73
+ }
74
+
75
+ .astryx-app-shell__header[data-variant='surface'],
76
+ .astryx-app-shell__sidenav[data-variant='surface'] {
77
+ background-color: var(--astryx-color-background-surface, #fff);
78
+ }
79
+
80
+ .astryx-app-shell__banner {
81
+ flex-shrink: 0;
82
+ }
83
+
84
+ .astryx-app-shell__mobile-bar {
85
+ display: flex;
86
+ align-items: center;
87
+ height: var(--astryx-spacing-12, 48px);
88
+ padding-inline: var(--astryx-spacing-2, 8px);
89
+ }
90
+
91
+ .astryx-app-shell__mobile-bar[data-variant='wash'],
92
+ .astryx-app-shell__mobile-bar[data-variant='elevated'] {
93
+ background-color: var(--astryx-color-background-body, #f1f1f1);
94
+ }
95
+
96
+ .astryx-app-shell__mobile-bar[data-variant='surface'],
97
+ .astryx-app-shell__mobile-bar[data-variant='section'] {
98
+ background-color: var(--astryx-color-background-surface, #fff);
99
+ }
100
+
101
+ .astryx-app-shell__mobile-nav {
102
+ display: flex;
103
+ align-items: center;
104
+ width: 100%;
105
+ min-width: 0;
106
+ height: 100%;
107
+ }
108
+
109
+ .astryx-app-shell__mobile-nav > .astryx-mobile-nav-toggle {
110
+ flex: none;
111
+ margin-inline-start: auto;
112
+ }
113
+
114
+ .astryx-app-shell__main {
115
+ display: contents;
116
+ }
117
+
118
+ .astryx-app-shell__main[data-elevated] {
119
+ position: relative;
120
+ display: flex;
121
+ flex: 1;
122
+ min-height: 0;
123
+ height: 100%;
124
+ }
125
+
126
+ .astryx-app-shell__backdrop {
127
+ position: absolute;
128
+ inset: 0;
129
+ background-color: var(--astryx-color-background-surface, #fff);
130
+ border-start-start-radius: var(--astryx-radius-page, 1.75rem);
131
+ pointer-events: none;
132
+ }
133
+
134
+ .astryx-app-shell__content:focus {
135
+ outline: none;
136
+ }
137
+
138
+ .astryx-app-shell__content[data-variant='wash'] {
139
+ background-color: var(--astryx-color-background-body, #f1f1f1);
140
+ }
141
+
142
+ .astryx-app-shell__content[data-variant='surface'],
143
+ .astryx-app-shell__content[data-variant='elevated']:not([data-corner]) {
144
+ background-color: var(--astryx-color-background-surface, #fff);
145
+ }
146
+
147
+ .astryx-app-shell__content[data-corner] {
148
+ background-color: transparent;
149
+ isolation: isolate;
150
+ }
151
+ }
@@ -0,0 +1,49 @@
1
+ @layer astryx.reset, astryx.tokens, astryx.base, astryx.components, astryx.overrides;
2
+
3
+ /*
4
+ * fit 的子元素尺寸放在 reset 层,选择器特异性为零。
5
+ * 子元素自己写的宽高和 object-fit 仍然能盖过这里。
6
+ */
7
+ @layer astryx.reset {
8
+ :where([data-astryx-aspect-ratio-override='cover'], [data-astryx-aspect-ratio-override='contain']) > :where(*) {
9
+ width: 100%;
10
+ height: 100%;
11
+ }
12
+
13
+ :where([data-astryx-aspect-ratio-override='cover']) > :where(img, video) {
14
+ object-fit: cover;
15
+ }
16
+
17
+ :where([data-astryx-aspect-ratio-override='contain']) > :where(img, video) {
18
+ object-fit: contain;
19
+ }
20
+ }
21
+
22
+ @layer astryx.components {
23
+ .astryx-aspect-ratio {
24
+ position: relative;
25
+ width: 100%;
26
+ overflow: clip;
27
+ min-height: 0;
28
+ flex-shrink: 0;
29
+ aspect-ratio: var(--astryx-aspect-ratio);
30
+ }
31
+
32
+ .astryx-aspect-ratio[data-shape='ellipse'] {
33
+ border-radius: 50%;
34
+ }
35
+
36
+ .astryx-aspect-ratio__child {
37
+ position: absolute;
38
+ top: 0;
39
+ inset-inline-start: 0;
40
+ width: 100%;
41
+ height: 100%;
42
+ }
43
+
44
+ .astryx-aspect-ratio__child[data-fit='center'] {
45
+ display: flex;
46
+ align-items: center;
47
+ justify-content: center;
48
+ }
49
+ }
package/styles/card.css CHANGED
@@ -29,6 +29,10 @@
29
29
  --container-padding-inline-end: var(--_card-padding-inline-end);
30
30
  --container-padding-block-start: var(--_card-padding-block-start);
31
31
  --container-padding-block-end: var(--_card-padding-block-end);
32
+ --layout-padding-own-outer-x: initial;
33
+ --layout-padding-own-outer-y: initial;
34
+ --layout-padding-outer-x: var(--_card-padding-inline-start);
35
+ --layout-padding-outer-y: var(--_card-padding-block-start);
32
36
  }
33
37
 
34
38
  .astryx-card[data-scrollable='true'] {
@@ -111,7 +115,7 @@
111
115
  }
112
116
 
113
117
  .astryx-card[data-variant='muted'] {
114
- background-color: var(--astryx-card-muted-background, #f5f5f5);
118
+ background-color: var(--astryx-card-muted-background, var(--astryx-color-background-muted, #f1f1f1));
115
119
  }
116
120
 
117
121
  .astryx-card[data-variant='blue'] {