@ac-design/design-system 2.10.3 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -40
- package/dist/lib/compat.css +3 -0
- package/dist/lib/components/AcCard.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/lib/components/AcFontScale.vue.d.ts +3 -0
- package/dist/lib/components/AcFontScale.vue_vue_type_script_setup_true_lang.js +24 -20
- package/dist/lib/components/AcFormArray.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/lib/components/AcSidebar.vue.d.ts +3 -0
- package/dist/lib/components/AcSidebar.vue_vue_type_script_setup_true_lang.js +7 -3
- package/dist/lib/components/AcTable.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/lib/components/AcThemeMode.vue.d.ts +3 -0
- package/dist/lib/components/AcThemeMode.vue_vue_type_script_setup_true_lang.js +38 -34
- package/dist/lib/components/AcUserMenu.vue_vue_type_script_setup_true_lang.js +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AppsCode Design System
|
|
2
2
|
|
|
3
|
-
The design system for every AppsCode console (cluster-ui, kubedb-ui, platform-ui, billing,
|
|
3
|
+
The design system for every AppsCode console (cloud-ui, cluster-ui, kubedb-ui, platform-ui, billing-ui, selfhost-ui…): a **Tailwind CSS v4 theme** and **Vue 3 components**, with a documentation site that shows every component live.
|
|
4
4
|
|
|
5
5
|
It replaces the old Bulma/SCSS library (`@appscode/design-system` 2.x). Every component the apps import from the old library has a replacement here, and the docs' Migration page maps the old props to the new ones.
|
|
6
6
|
|
|
@@ -14,9 +14,10 @@ npm run dev # docs site at http://localhost:5173
|
|
|
14
14
|
| | |
|
|
15
15
|
| --- | --- |
|
|
16
16
|
| **Theme** | `src/lib/theme.css`: colour scales, semantic tokens (text, borders, surfaces), type scale, radii, shadows and a full dark theme, as a Tailwind `@theme`. |
|
|
17
|
-
| **Components** |
|
|
18
|
-
| **Editors** | `AcCodeEditor` and `AcFileEditor` on CodeMirror 6, in
|
|
19
|
-
| **
|
|
17
|
+
| **Components** | 101 Vue components (counting sub-parts such as `AcDropdownItem`) in eight groups, listed below. |
|
|
18
|
+
| **Editors** | `AcCodeEditor` and `AcFileEditor` on CodeMirror 6, in the `/editor` entry so other apps don't bundle CodeMirror. |
|
|
19
|
+
| **Charts** | Seven charts on Apache ECharts 6 (cloud-ui's engine), in the `/charts` entry. `echarts` is an optional peer dependency. |
|
|
20
|
+
| **Composables** | `useColorMode()` (light/dark/system), `useFontScale()` (text size), `useToast()` (notifications), `useBrandColor()` (re-hue the brand at runtime), `useTablePagination()` and `useApiPagination()`, `useBulkSelection()`, `useFormValidation()`, and `copyText()`. |
|
|
20
21
|
| **Logo** | `AcLogo`: the AppsCode logo and mark as inline SVG that follows dark mode. |
|
|
21
22
|
| **Docs site** | Getting started, foundations, a page per component (live playground, examples, guidelines, accessibility, API tables) and full example pages. |
|
|
22
23
|
|
|
@@ -24,15 +25,15 @@ npm run dev # docs site at http://localhost:5173
|
|
|
24
25
|
|
|
25
26
|
| Group | Components |
|
|
26
27
|
| --- | --- |
|
|
27
|
-
| Element | Button, Button Group, Badge, Tag, Avatar, Alert, Banner, Card, Divider, Kbd, Copy Button |
|
|
28
|
-
| Feedback | Spinner
|
|
29
|
-
| Form | Input, Number Input,
|
|
30
|
-
| Overlay | Modal,
|
|
31
|
-
| Layout | Sidebar, Navbar, Header, Content Table, Section, Accordion, Status Bar, Footer |
|
|
32
|
-
| Navigation | Breadcrumb, Tabs, Steps, Pagination, Side Tabs, App Switcher, Cluster Switcher, Notifications
|
|
33
|
-
| Data | Table, Bulk Action Bar, Info Table, Cell Value |
|
|
34
|
-
| Cards | Stat Card, Feature Card, Resource Card, Usage Card |
|
|
35
|
-
| Charts (`/charts`) | Line Chart, Area Chart, Bar Chart, Donut Chart |
|
|
28
|
+
| Element | Button, Button Group, Badge, Tag, Avatar, Alert, Banner, Card, Divider, Kbd, Copy Button, Command Block, Check List |
|
|
29
|
+
| Feedback | Spinner and Preloader, Loader, Skeleton, Progress, Circular Progress, Toast, Empty State, Error State |
|
|
30
|
+
| Form | Input, Number Input, Textarea, Code Editor, File Editor, Select, Combobox, Tag Input, CheckBox, CheckRadio, Radio Card, Switch, Switch Card, Search Bar, File Upload, Slider, Date Picker, Month Picker, Color Input, Time Picker, Form, Form Array, Key-Value Input, Taint Input, Theme Mode, Font Scale |
|
|
31
|
+
| Overlay | Modal, Delete Modal, Confirm Modal, Side Panel, Dropdown, Popover, Tooltip |
|
|
32
|
+
| Layout | Page, Sidebar, Navbar, Header, Product Hero, Content Table, Section Content, Settings Row, Accordion, Status Bar, Footer |
|
|
33
|
+
| Navigation | Breadcrumb, Tabs, Steps, Pagination, Locale Switcher, Side Tabs, App Switcher, Cluster Switcher, Notifications |
|
|
34
|
+
| Data | Table, Bulk Action Bar, Info Table, List, Cell Value |
|
|
35
|
+
| Cards | Stat Card, Feature Card, Resource Card, Usage Card, Cost Summary |
|
|
36
|
+
| Charts (`/charts`) | Line Chart, Area Chart, Bar Chart, Donut Chart, Map Chart, Graph Chart, Tree Chart |
|
|
36
37
|
|
|
37
38
|
Example pages put them together: a database list, a database detail page, a create wizard, settings, empty and error states, and a full app shell.
|
|
38
39
|
|
|
@@ -42,14 +43,19 @@ The look and voice are the AppsCode Cloud console's (`cloud-ui`), so the system
|
|
|
42
43
|
|
|
43
44
|
- **Type:** Roboto for the interface, Google Sans Flex for headings and JetBrains Mono for code and resource names, on a 14px base.
|
|
44
45
|
- **Colour:** white cards on a `#f9fafb` page, neutral greys (`#252525` text, `#5c5c5c` descriptions, one `#ebebeb` border), the `#00a651` brand green, and success, info, warning, danger and pending statuses, each with an AA `-strong` text colour.
|
|
45
|
-
- **Shape:**
|
|
46
|
+
- **Shape:** 42px buttons and fields with a 10px radius, 14px cards and 16px dialogs. Cards rest on a border; shadows mark only what floats.
|
|
46
47
|
- **Focus:** a `focus-ring` utility (primary border and a 2px halo) on form fields, and a 2px offset ring on buttons.
|
|
47
48
|
- **Dark mode:** class-based. Every token has a dark value, so components need no dark-specific code.
|
|
48
49
|
- **Icons:** [Lucide](https://lucide.dev) (`@lucide/vue`). Components never draw their own SVG icons.
|
|
49
50
|
|
|
50
51
|
## Using it in an app
|
|
51
52
|
|
|
52
|
-
The package is `@ac-design/design-system`
|
|
53
|
+
The package is [`@ac-design/design-system`](https://www.npmjs.com/package/@ac-design/design-system) on npm. `npm run build:lib` writes it to `dist/lib`, and `npm pack` makes an installable tarball.
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
npm install @ac-design/design-system @lucide/vue
|
|
57
|
+
npm install echarts # only if you use /charts
|
|
58
|
+
```
|
|
53
59
|
|
|
54
60
|
## Styling rule
|
|
55
61
|
|
|
@@ -59,54 +65,50 @@ There are two ways to load the styles:
|
|
|
59
65
|
|
|
60
66
|
| The app… | Load | Tailwind in the app |
|
|
61
67
|
| --- | --- | --- |
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
65
|
-
### In an app that still loads the old styles
|
|
68
|
+
| runs Tailwind v4 (cloud-ui, cluster-ui, kubedb-ui, platform-ui and new apps) | `theme.css` | Yes |
|
|
69
|
+
| still loads the old Bulma/SCSS design system and has no Tailwind | `compat.css` | No |
|
|
66
70
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
```sh
|
|
70
|
-
# installed next to the old 2.x package, under a second name
|
|
71
|
-
npm install @appscode/ds-next@npm:@ac-design/design-system@2.0.0 @lucide/vue
|
|
72
|
-
```
|
|
71
|
+
### In an app with Tailwind v4
|
|
73
72
|
|
|
74
73
|
```ts
|
|
75
|
-
// main.ts
|
|
76
|
-
import "./assets/styles/scss/main.scss";
|
|
74
|
+
// main.ts: fonts once
|
|
77
75
|
import "@fontsource-variable/roboto";
|
|
78
76
|
import "@fontsource-variable/google-sans-flex/opsz.css";
|
|
79
77
|
import "@fontsource-variable/jetbrains-mono";
|
|
80
|
-
import "@appscode/ds-next/compat.css";
|
|
81
78
|
```
|
|
82
79
|
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
```css
|
|
81
|
+
/* your main CSS file */
|
|
82
|
+
@import "tailwindcss";
|
|
83
|
+
@import "@ac-design/design-system/theme.css";
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### In an app with only the old styles
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
The docs page **Getting Started → Existing Apps** has the full guide. In short:
|
|
87
89
|
|
|
88
90
|
```ts
|
|
89
|
-
// main.ts:
|
|
91
|
+
// main.ts (Vite), or the `css` list in nuxt.config.ts: after the old styles
|
|
92
|
+
import "./assets/styles/scss/main.scss";
|
|
90
93
|
import "@fontsource-variable/roboto";
|
|
91
94
|
import "@fontsource-variable/google-sans-flex/opsz.css";
|
|
92
95
|
import "@fontsource-variable/jetbrains-mono";
|
|
96
|
+
import "@ac-design/design-system/compat.css";
|
|
93
97
|
```
|
|
94
98
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
@import "tailwindcss";
|
|
98
|
-
@import "@ac-design/design-system/theme.css";
|
|
99
|
-
```
|
|
99
|
+
- **`compat.css`** is the library's styles, precompiled and fenced in: they apply only inside new components, and win over the old `!important` utilities there. Old pages don't change; this was checked pixel by pixel in kubedb-ui.
|
|
100
|
+
- **Don't put utility classes on new components** while both are loaded. Wrap the component in your own element for spacing.
|
|
100
101
|
|
|
101
102
|
### Either way
|
|
102
103
|
|
|
103
104
|
```ts
|
|
104
105
|
import { AcButton, AcInput, useToast } from "@ac-design/design-system";
|
|
105
106
|
import { AcCodeEditor, AcFileEditor } from "@ac-design/design-system/editor";
|
|
107
|
+
import { AcLineChart, AcDonutChart } from "@ac-design/design-system/charts";
|
|
106
108
|
```
|
|
107
109
|
|
|
108
110
|
- **Requirements:** Vue 3.5+, Vite 5+ or Nuxt 3+, and TypeScript with `moduleResolution: "bundler"`. Every component renders on the server, so Nuxt SSR works.
|
|
109
|
-
- **Peer dependencies:** `vue` ^3.5 and `@lucide/vue` ^1.0
|
|
111
|
+
- **Peer dependencies:** `vue` ^3.5 and `@lucide/vue` ^1.0, plus `echarts` ^6 (optional) for `/charts`. CodeMirror, Ajv and `yaml` are regular dependencies, bundled only by apps that import from `/editor`.
|
|
110
112
|
- **Dark mode:** put `.dark` on `<html>` (the old `.is-dark-theme` class works too), or call `useColorMode().setMode("dark" | "light" | "system")`. The user's choice is saved under the old `themeMode` localStorage key.
|
|
111
113
|
- **Toasts:** mount `<AcToaster />` once near the root, then call `useToast().success("Saved")` anywhere.
|
|
112
114
|
- **Brand colour:** `useBrandColor().setColor("#0066cc")` re-hues the primary scale. The old `HexToHSL`, `setThemeHSL` and `getThemeHSL` helpers are exported under the same names.
|
|
@@ -118,6 +120,7 @@ import { AcCodeEditor, AcFileEditor } from "@ac-design/design-system/editor";
|
|
|
118
120
|
| --- | --- |
|
|
119
121
|
| `npm run dev` | Regenerates the API data, then starts the docs site at http://localhost:5173 |
|
|
120
122
|
| `npm run build` | Regenerates the API data, type-checks, and builds the docs site into `dist/` |
|
|
123
|
+
| `npm run preview` | Serves the built docs site from `dist/` |
|
|
121
124
|
| `npm run build:lib` | Builds the library into `dist/lib`: ES modules, `.d.ts` files, `theme.css` and `compat.css` |
|
|
122
125
|
| `npm run type-check` | `vue-tsc` over the whole project |
|
|
123
126
|
| `npm run meta` | Regenerates `src/docs/generated/component-meta.json` (the API tables) from the components' types |
|
|
@@ -135,7 +138,8 @@ src/
|
|
|
135
138
|
index.ts component exports, sorted
|
|
136
139
|
types.ts shared types (Tone, Variant, Option, SelectOption)
|
|
137
140
|
editor/ the /editor entry: index.ts, CodeMirror theme, YAML/JSON Schema checks
|
|
138
|
-
|
|
141
|
+
charts/ the /charts entry: index.ts, ECharts setup, ChartFrame.vue (legend, tooltip, sr-only table)
|
|
142
|
+
composables/ useColorMode, useFontScale, useToast, useBrandColor, pagination, selection and form helpers
|
|
139
143
|
docs/ the documentation site
|
|
140
144
|
nav.ts every page: path, title, description, section, group, component
|
|
141
145
|
router.ts hash router built from nav.ts
|
|
@@ -151,7 +155,7 @@ scripts/
|
|
|
151
155
|
build-compat.mjs builds compat.css for apps that still load the old styles
|
|
152
156
|
public/ favicon, logos
|
|
153
157
|
vite.config.ts docs site
|
|
154
|
-
vite.lib.config.ts library build (
|
|
158
|
+
vite.lib.config.ts library build (three entries: index, editor/index and charts/index)
|
|
155
159
|
```
|
|
156
160
|
|
|
157
161
|
## Contributing
|
package/dist/lib/compat.css
CHANGED
|
@@ -5415,6 +5415,9 @@ button:is([data-ac-ds], [data-ac-ds] *), input:where([type="button"], [type="res
|
|
|
5415
5415
|
font-size: var(--text-xs) !important;
|
|
5416
5416
|
line-height: var(--tw-leading, var(--text-xs--line-height)) !important;
|
|
5417
5417
|
}
|
|
5418
|
+
.max-sm\:has-\[\>\.w-full\]\:basis-full:has( > .w-full):where([data-ac-ds], [data-ac-ds] *) {
|
|
5419
|
+
flex-basis: 100% !important;
|
|
5420
|
+
}
|
|
5418
5421
|
}
|
|
5419
5422
|
@media (width >= 40rem) {
|
|
5420
5423
|
.sm\:inset-x-auto:where([data-ac-ds], [data-ac-ds] *) {
|
|
@@ -12,7 +12,7 @@ var g = {
|
|
|
12
12
|
class: "mt-0.5 text-xs leading-4 text-muted"
|
|
13
13
|
}, b = {
|
|
14
14
|
key: 1,
|
|
15
|
-
class: "flex max-w-full min-w-0 shrink-0 flex-wrap items-center gap-2 sm:flex-nowrap"
|
|
15
|
+
class: "flex max-w-full min-w-0 shrink-0 flex-wrap items-center gap-2 max-sm:has-[>.w-full]:basis-full sm:flex-nowrap"
|
|
16
16
|
}, x = /*@__PURE__*/ c({
|
|
17
17
|
__name: "AcCard",
|
|
18
18
|
props: {
|
|
@@ -4,6 +4,8 @@ export interface Props {
|
|
|
4
4
|
defaultScale?: FontScale | number;
|
|
5
5
|
/** `icons` is a compact switch of four "A"s; `labels` adds the words, for menus and settings pages. */
|
|
6
6
|
display?: "icons" | "labels";
|
|
7
|
+
/** Fills its row and shares the width between the buttons, e.g. in a 256px menu where the labelled switch would overflow. */
|
|
8
|
+
block?: boolean;
|
|
7
9
|
}
|
|
8
10
|
declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
11
|
"set:scale": (scale: number) => any;
|
|
@@ -11,6 +13,7 @@ declare const __VLS_export: import("vue").DefineComponent<Props, {}, {}, {}, {},
|
|
|
11
13
|
"onSet:scale"?: ((scale: number) => any) | undefined;
|
|
12
14
|
}>, {
|
|
13
15
|
display: "icons" | "labels";
|
|
16
|
+
block: boolean;
|
|
14
17
|
defaultScale: FontScale | number;
|
|
15
18
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
19
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
import { FONT_SCALES as e, useFontScale as t } from "../composables/useFontScale.js";
|
|
2
2
|
import { Fragment as n, createElementBlock as r, createElementVNode as i, defineComponent as a, normalizeClass as o, openBlock as s, renderList as c, toDisplayString as l, unref as u } from "vue";
|
|
3
3
|
//#region src/lib/components/AcFontScale.vue?vue&type=script&setup=true&lang.ts
|
|
4
|
-
var d =
|
|
5
|
-
role: "radiogroup",
|
|
6
|
-
"aria-label": "Text size",
|
|
7
|
-
class: "inline-flex items-center gap-1 rounded-10 bg-surface-sunken p-1",
|
|
8
|
-
"data-ac-ds": "",
|
|
9
|
-
"data-testid": "ac-font-scale"
|
|
10
|
-
}, f = [
|
|
4
|
+
var d = [
|
|
11
5
|
"aria-checked",
|
|
12
6
|
"aria-label",
|
|
13
7
|
"title",
|
|
14
8
|
"onClick"
|
|
15
|
-
],
|
|
9
|
+
], f = { key: 1 }, p = /*@__PURE__*/ a({
|
|
16
10
|
__name: "AcFontScale",
|
|
17
11
|
props: {
|
|
18
12
|
defaultScale: { default: "default" },
|
|
19
|
-
display: { default: "icons" }
|
|
13
|
+
display: { default: "icons" },
|
|
14
|
+
block: {
|
|
15
|
+
type: Boolean,
|
|
16
|
+
default: !1
|
|
17
|
+
}
|
|
20
18
|
},
|
|
21
19
|
emits: ["set:scale"],
|
|
22
|
-
setup(a, { emit:
|
|
23
|
-
let
|
|
20
|
+
setup(a, { emit: p }) {
|
|
21
|
+
let m = a, h = p, g = [
|
|
24
22
|
{
|
|
25
23
|
value: "small",
|
|
26
24
|
label: "Small",
|
|
@@ -41,25 +39,31 @@ var d = {
|
|
|
41
39
|
label: "Larger",
|
|
42
40
|
glyph: "text-2xl"
|
|
43
41
|
}
|
|
44
|
-
], { scale:
|
|
45
|
-
function
|
|
46
|
-
|
|
42
|
+
], { scale: _, preset: v, setScale: y } = t({ defaultScale: typeof m.defaultScale == "number" ? m.defaultScale : e[m.defaultScale] });
|
|
43
|
+
function b(e) {
|
|
44
|
+
y(e), h("set:scale", _.value);
|
|
47
45
|
}
|
|
48
|
-
return (e, t) => (s(), r("div",
|
|
46
|
+
return (e, t) => (s(), r("div", {
|
|
47
|
+
role: "radiogroup",
|
|
48
|
+
"aria-label": "Text size",
|
|
49
|
+
class: o(["items-center gap-1 rounded-10 bg-surface-sunken p-1", a.block ? "flex w-full" : "inline-flex"]),
|
|
50
|
+
"data-ac-ds": "",
|
|
51
|
+
"data-testid": "ac-font-scale"
|
|
52
|
+
}, [(s(), r(n, null, c(g, (e) => i("button", {
|
|
49
53
|
key: e.value,
|
|
50
54
|
type: "button",
|
|
51
55
|
role: "radio",
|
|
52
|
-
"aria-checked": u(
|
|
56
|
+
"aria-checked": u(v) === e.value,
|
|
53
57
|
"aria-label": a.display === "icons" ? `${e.label} text` : void 0,
|
|
54
58
|
title: a.display === "icons" ? `${e.label} text` : void 0,
|
|
55
|
-
class: o(["inline-flex h-7 cursor-pointer items-center justify-center gap-1.5 rounded-8 text-base font-medium transition-[background-color,color,box-shadow] duration-200 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset focus-visible:outline-none", [a.display === "icons" ? "w-7" : "px-3", u(
|
|
56
|
-
onClick: (t) =>
|
|
59
|
+
class: o(["inline-flex h-7 cursor-pointer items-center justify-center gap-1.5 rounded-8 text-base font-medium transition-[background-color,color,box-shadow] duration-200 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset focus-visible:outline-none", [a.display === "icons" ? "w-7" : a.block ? "flex-1 px-1" : "px-3", u(v) === e.value ? "bg-surface text-heading shadow-sm" : "text-muted hover:text-heading"]]),
|
|
60
|
+
onClick: (t) => b(e.value)
|
|
57
61
|
}, [a.display === "icons" ? (s(), r("span", {
|
|
58
62
|
key: 0,
|
|
59
63
|
class: o(["leading-none font-semibold", e.glyph]),
|
|
60
64
|
"aria-hidden": "true"
|
|
61
|
-
}, "A", 2)) : (s(), r("span",
|
|
65
|
+
}, "A", 2)) : (s(), r("span", f, l(e.label), 1))], 10, d)), 64))], 2));
|
|
62
66
|
}
|
|
63
67
|
});
|
|
64
68
|
//#endregion
|
|
65
|
-
export {
|
|
69
|
+
export { p as default };
|
|
@@ -12,7 +12,7 @@ var _e = ["aria-describedby"], ve = { class: "flex min-h-8 items-center justify-
|
|
|
12
12
|
}, be = {
|
|
13
13
|
key: 2,
|
|
14
14
|
class: "sr-only"
|
|
15
|
-
}, xe = { class: "ac-scrollbar" }, Se = { class: "w-full border-separate border-spacing-0 text-base" }, Ce = { class: "sr-only" }, we = {
|
|
15
|
+
}, xe = { class: "ac-scrollbar relative" }, Se = { class: "w-full border-separate border-spacing-0 text-base" }, Ce = { class: "sr-only" }, we = {
|
|
16
16
|
key: 0,
|
|
17
17
|
scope: "col",
|
|
18
18
|
class: "h-10 w-px border-b border-border bg-surface-sunken/50 px-3 text-right"
|
|
@@ -7,6 +7,8 @@ export interface Props {
|
|
|
7
7
|
collapsible?: boolean;
|
|
8
8
|
/** Keeps the sidebar inside its parent instead of the viewport: the mobile drawer and backdrop use `absolute`, and the mobile layout follows the parent's width. Give the parent `relative`, `overflow-hidden` and a height. For previews and embedded shells. */
|
|
9
9
|
contained?: boolean;
|
|
10
|
+
/** Narrows the docked sidebar from 256px to 208px between 1024px and 1279px, as cloud-ui. Set `false` to keep 256px when labels are long. */
|
|
11
|
+
shrink?: boolean;
|
|
10
12
|
/** Width in px below which the sidebar becomes an off-canvas drawer: the window's width, or the parent's with `contained`. `0` keeps it docked. */
|
|
11
13
|
breakpoint?: number;
|
|
12
14
|
/** With the sidebar collapsed to the rail, opens it to full width over the page while the pointer or keyboard focus is inside, then folds it back. The page doesn't shift. */
|
|
@@ -61,6 +63,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
61
63
|
top: string;
|
|
62
64
|
dark: boolean;
|
|
63
65
|
contained: boolean;
|
|
66
|
+
shrink: boolean;
|
|
64
67
|
breakpoint: number;
|
|
65
68
|
hoverExpand: boolean;
|
|
66
69
|
footerScrolls: boolean;
|
|
@@ -35,6 +35,10 @@ var E = [
|
|
|
35
35
|
type: Boolean,
|
|
36
36
|
default: !1
|
|
37
37
|
},
|
|
38
|
+
shrink: {
|
|
39
|
+
type: Boolean,
|
|
40
|
+
default: !0
|
|
41
|
+
},
|
|
38
42
|
breakpoint: { default: 768 },
|
|
39
43
|
hoverExpand: {
|
|
40
44
|
type: Boolean,
|
|
@@ -81,17 +85,17 @@ var E = [
|
|
|
81
85
|
top: k.top,
|
|
82
86
|
height: `calc(100dvh - ${k.top})`
|
|
83
87
|
}), _e = n(() => {
|
|
84
|
-
let e = k.dark ? "dark border-r border-border bg-sidebar text-body
|
|
88
|
+
let e = k.dark ? "dark border-r border-border bg-sidebar text-body" : "border-r border-border bg-sidebar-panel/95 text-body backdrop-blur-sm";
|
|
85
89
|
return F.value ? [
|
|
86
90
|
e,
|
|
87
91
|
k.contained ? "absolute" : "fixed",
|
|
88
|
-
"inset-y-0 left-0 z-[80] w-64 duration-300 ease-out-soft motion-reduce:transition-none",
|
|
92
|
+
"inset-y-0 left-0 z-[80] w-64 shadow-sm duration-300 ease-out-soft motion-reduce:transition-none",
|
|
89
93
|
j.value ? "visible translate-x-0 transition-[translate]" : "invisible -translate-x-full transition-[translate,visibility]"
|
|
90
94
|
] : [
|
|
91
95
|
e,
|
|
92
96
|
B.value ? [k.contained ? "absolute inset-y-0 left-0" : "fixed left-0", "z-30 shadow-xl"] : k.contained ? "relative h-full" : k.fixed ? "fixed left-0 z-30" : "sticky",
|
|
93
97
|
"transition-[width] duration-200 ease-out-soft motion-reduce:transition-none",
|
|
94
|
-
V.value ? "w-14" : k.contained ? "w-64" : "w-64 lg:w-52 xl:w-64"
|
|
98
|
+
V.value ? "w-14" : k.contained || !k.shrink ? "w-64" : "w-64 lg:w-52 xl:w-64"
|
|
95
99
|
];
|
|
96
100
|
});
|
|
97
101
|
function J() {
|
|
@@ -4,7 +4,7 @@ import n from "./AcPagination.js";
|
|
|
4
4
|
import { Fragment as r, computed as i, createBlock as a, createCommentVNode as o, createElementBlock as s, createElementVNode as c, createTextVNode as l, createVNode as u, defineComponent as d, getCurrentInstance as f, mergeModels as p, mergeProps as ee, normalizeClass as m, normalizeStyle as h, openBlock as g, renderList as _, renderSlot as v, resolveDynamicComponent as y, toDisplayString as b, unref as x, useId as te, useModel as S, useSlots as ne, watch as re, withCtx as C, withModifiers as w } from "vue";
|
|
5
5
|
import { Check as T, ChevronDown as ie, ChevronRight as ae, ChevronUp as oe, Minus as se } from "@lucide/vue";
|
|
6
6
|
//#region src/lib/components/AcTable.vue?vue&type=script&setup=true&lang.ts
|
|
7
|
-
var ce = { class: "ac-scrollbar" }, le = { class: "w-full border-separate border-spacing-0 text-base" }, ue = { class: "relative flex size-[18px]" }, de = [
|
|
7
|
+
var ce = { class: "ac-scrollbar relative" }, le = { class: "w-full border-separate border-spacing-0 text-base" }, ue = { class: "relative flex size-[18px]" }, de = [
|
|
8
8
|
"checked",
|
|
9
9
|
"indeterminate",
|
|
10
10
|
"disabled"
|
|
@@ -4,6 +4,8 @@ export interface Props {
|
|
|
4
4
|
defaultMode?: ColorMode;
|
|
5
5
|
/** `icons` is a compact 3-icon switch; `labels` adds the words, for menus and settings pages; `toggle` is cloud-ui's sun/moon switch for the navbar (64×32px), light or dark only. */
|
|
6
6
|
display?: "icons" | "labels" | "toggle";
|
|
7
|
+
/** Fills its row and shares the width between the buttons, e.g. in a 256px menu where the labelled switch would overflow. Not for `toggle`. */
|
|
8
|
+
block?: boolean;
|
|
7
9
|
}
|
|
8
10
|
type __VLS_Props = Props;
|
|
9
11
|
type __VLS_ModelProps = {
|
|
@@ -19,6 +21,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {},
|
|
|
19
21
|
"onUpdate:dark"?: ((value: boolean | undefined) => any) | undefined;
|
|
20
22
|
}>, {
|
|
21
23
|
display: "icons" | "labels" | "toggle";
|
|
24
|
+
block: boolean;
|
|
22
25
|
defaultMode: ColorMode;
|
|
23
26
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
27
|
declare const _default: typeof __VLS_export;
|
|
@@ -2,23 +2,20 @@ import { useColorMode as e } from "../composables/useColorMode.js";
|
|
|
2
2
|
import { Fragment as t, computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, createVNode as s, defineComponent as c, mergeModels as l, normalizeClass as u, onBeforeUnmount as d, openBlock as f, ref as p, renderList as m, resolveDynamicComponent as h, toDisplayString as g, unref as _, useModel as v, watch as y } from "vue";
|
|
3
3
|
import { Monitor as b, Moon as x, Sun as S } from "@lucide/vue";
|
|
4
4
|
//#region src/lib/components/AcThemeMode.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
var C = ["aria-checked", "title"], w =
|
|
6
|
-
key: 1,
|
|
7
|
-
role: "radiogroup",
|
|
8
|
-
"aria-label": "Theme",
|
|
9
|
-
class: "inline-flex items-center gap-1 rounded-10 bg-surface-sunken p-1",
|
|
10
|
-
"data-ac-ds": "",
|
|
11
|
-
"data-testid": "ac-theme-mode"
|
|
12
|
-
}, T = [
|
|
5
|
+
var C = ["aria-checked", "title"], w = [
|
|
13
6
|
"aria-checked",
|
|
14
7
|
"aria-label",
|
|
15
8
|
"title",
|
|
16
9
|
"onClick"
|
|
17
|
-
],
|
|
10
|
+
], T = { key: 0 }, E = /*@__PURE__*/ c({
|
|
18
11
|
__name: "AcThemeMode",
|
|
19
12
|
props: /*@__PURE__*/ l({
|
|
20
13
|
defaultMode: { default: "light" },
|
|
21
|
-
display: { default: "icons" }
|
|
14
|
+
display: { default: "icons" },
|
|
15
|
+
block: {
|
|
16
|
+
type: Boolean,
|
|
17
|
+
default: !1
|
|
18
|
+
}
|
|
22
19
|
}, {
|
|
23
20
|
dark: {
|
|
24
21
|
type: Boolean,
|
|
@@ -28,7 +25,7 @@ var C = ["aria-checked", "title"], w = {
|
|
|
28
25
|
}),
|
|
29
26
|
emits: /*@__PURE__*/ l(["set:theme"], ["update:dark"]),
|
|
30
27
|
setup(c, { emit: l }) {
|
|
31
|
-
let
|
|
28
|
+
let E = c, D = v(c, "dark"), O = l, k = [
|
|
32
29
|
{
|
|
33
30
|
value: "light",
|
|
34
31
|
label: "Light",
|
|
@@ -44,60 +41,67 @@ var C = ["aria-checked", "title"], w = {
|
|
|
44
41
|
label: "System",
|
|
45
42
|
icon: b
|
|
46
43
|
}
|
|
47
|
-
],
|
|
48
|
-
function
|
|
49
|
-
if (
|
|
50
|
-
|
|
44
|
+
], A = D.value === void 0 ? e({ defaultMode: E.defaultMode }) : null, j = n(() => A ? A.isDark.value : !!D.value), M = n(() => A ? A.mode.value : D.value ? "dark" : "light"), N = p(j.value), P;
|
|
45
|
+
function F(e) {
|
|
46
|
+
if (A) {
|
|
47
|
+
A.setMode(e), O("set:theme", j.value ? "dark" : "light");
|
|
51
48
|
return;
|
|
52
49
|
}
|
|
53
50
|
let t = e === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches : e === "dark";
|
|
54
|
-
|
|
51
|
+
D.value = t, O("set:theme", t ? "dark" : "light");
|
|
55
52
|
}
|
|
56
|
-
function
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
function I() {
|
|
54
|
+
N.value = !N.value, clearTimeout(P), P = setTimeout(() => {
|
|
55
|
+
P = void 0, F(N.value ? "dark" : "light");
|
|
59
56
|
}, 200);
|
|
60
57
|
}
|
|
61
|
-
return y(
|
|
62
|
-
|
|
63
|
-
}), d(() => clearTimeout(
|
|
58
|
+
return y(j, (e) => {
|
|
59
|
+
P === void 0 && (N.value = e);
|
|
60
|
+
}), d(() => clearTimeout(P)), (e, n) => c.display === "toggle" ? (f(), a("button", {
|
|
64
61
|
key: 0,
|
|
65
62
|
type: "button",
|
|
66
63
|
role: "switch",
|
|
67
|
-
"aria-checked":
|
|
64
|
+
"aria-checked": N.value,
|
|
68
65
|
"aria-label": "Dark mode",
|
|
69
|
-
title:
|
|
66
|
+
title: N.value ? "Switch to light mode" : "Switch to dark mode",
|
|
70
67
|
class: "relative inline-flex h-8 w-16 shrink-0 cursor-pointer items-center justify-center rounded-full border border-border focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface focus-visible:outline-none",
|
|
71
68
|
"data-ac-ds": "",
|
|
72
69
|
"data-testid": "ac-theme-mode",
|
|
73
|
-
onClick:
|
|
70
|
+
onClick: I
|
|
74
71
|
}, [
|
|
75
72
|
o("span", {
|
|
76
|
-
class: u(["inline-flex transition-[translate,rotate,opacity] duration-500 ease-[cubic-bezier(0.26,2,0.46,0.71)] motion-reduce:transition-none",
|
|
73
|
+
class: u(["inline-flex transition-[translate,rotate,opacity] duration-500 ease-[cubic-bezier(0.26,2,0.46,0.71)] motion-reduce:transition-none", N.value ? "translate-x-[10px] rotate-0 opacity-0" : "translate-x-[3px] rotate-[15deg] opacity-100"]),
|
|
77
74
|
"aria-hidden": "true"
|
|
78
75
|
}, [s(_(S), { class: "size-[19px] text-theme-sun" })], 2),
|
|
79
76
|
o("span", {
|
|
80
|
-
class: u(["size-[21px] shrink-0 rounded-full inset-ring-2 transition-[translate,background-color] duration-500 ease-[cubic-bezier(0.26,2,0.46,0.71)] motion-reduce:transition-none",
|
|
77
|
+
class: u(["size-[21px] shrink-0 rounded-full inset-ring-2 transition-[translate,background-color] duration-500 ease-[cubic-bezier(0.26,2,0.46,0.71)] motion-reduce:transition-none", N.value ? "-translate-x-[14px] bg-theme-moon inset-ring-white" : "translate-x-4 bg-theme-sun-soft inset-ring-theme-sun"]),
|
|
81
78
|
"aria-hidden": "true"
|
|
82
79
|
}, null, 2),
|
|
83
80
|
o("span", {
|
|
84
|
-
class: u(["inline-flex transition-[translate,rotate,opacity] duration-500 ease-[cubic-bezier(0.26,2.5,0.46,0.71)] motion-reduce:transition-none",
|
|
81
|
+
class: u(["inline-flex transition-[translate,rotate,opacity] duration-500 ease-[cubic-bezier(0.26,2.5,0.46,0.71)] motion-reduce:transition-none", N.value ? "-translate-x-[3px] -rotate-[15deg] opacity-100" : "-translate-x-2 rotate-0 opacity-0"]),
|
|
85
82
|
"aria-hidden": "true"
|
|
86
83
|
}, [s(_(x), { class: "size-[21px] text-heading" })], 2)
|
|
87
|
-
], 8, C)) : (f(), a("div",
|
|
84
|
+
], 8, C)) : (f(), a("div", {
|
|
85
|
+
key: 1,
|
|
86
|
+
role: "radiogroup",
|
|
87
|
+
"aria-label": "Theme",
|
|
88
|
+
class: u(["items-center gap-1 rounded-10 bg-surface-sunken p-1", c.block ? "flex w-full" : "inline-flex"]),
|
|
89
|
+
"data-ac-ds": "",
|
|
90
|
+
"data-testid": "ac-theme-mode"
|
|
91
|
+
}, [(f(), a(t, null, m(k, (e) => o("button", {
|
|
88
92
|
key: e.value,
|
|
89
93
|
type: "button",
|
|
90
94
|
role: "radio",
|
|
91
|
-
"aria-checked":
|
|
95
|
+
"aria-checked": M.value === e.value,
|
|
92
96
|
"aria-label": c.display === "icons" ? `${e.label} theme` : void 0,
|
|
93
97
|
title: c.display === "icons" ? `${e.label} theme` : void 0,
|
|
94
|
-
class: u(["inline-flex h-7 cursor-pointer items-center justify-center gap-1.5 rounded-8 text-base font-medium transition-[background-color,color,box-shadow] duration-200 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset focus-visible:outline-none", [c.display === "icons" ? "w-7" : "px-3",
|
|
95
|
-
onClick: (t) =>
|
|
98
|
+
class: u(["inline-flex h-7 cursor-pointer items-center justify-center gap-1.5 rounded-8 text-base font-medium transition-[background-color,color,box-shadow] duration-200 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset focus-visible:outline-none", [c.display === "icons" ? "w-7" : c.block ? "flex-1 px-1" : "px-3", M.value === e.value ? "bg-surface text-heading shadow-sm" : "text-muted hover:text-heading"]]),
|
|
99
|
+
onClick: (t) => F(e.value)
|
|
96
100
|
}, [(f(), r(h(e.icon), {
|
|
97
101
|
class: "size-4",
|
|
98
102
|
"aria-hidden": "true"
|
|
99
|
-
})), c.display === "labels" ? (f(), a("span",
|
|
103
|
+
})), c.display === "labels" ? (f(), a("span", T, g(e.label), 1)) : i("", !0)], 10, w)), 64))], 2));
|
|
100
104
|
}
|
|
101
105
|
});
|
|
102
106
|
//#endregion
|
|
103
|
-
export {
|
|
107
|
+
export { E as default };
|
|
@@ -360,6 +360,7 @@ var me = {
|
|
|
360
360
|
class: "mb-2 px-2 text-sm font-semibold tracking-[0.08em] text-muted uppercase"
|
|
361
361
|
}, "Theme", 8, Ye), f(r, {
|
|
362
362
|
display: "labels",
|
|
363
|
+
block: "",
|
|
363
364
|
"onSet:theme": o[3] ||= (e) => k("set:theme", e)
|
|
364
365
|
})], 8, Je)) : c("", !0),
|
|
365
366
|
p.showFontScale ? (g(), l("div", {
|
|
@@ -370,7 +371,10 @@ var me = {
|
|
|
370
371
|
}, [u("p", {
|
|
371
372
|
id: `${S(M)}-scale`,
|
|
372
373
|
class: "mb-2 px-2 text-sm font-semibold tracking-[0.08em] text-muted uppercase"
|
|
373
|
-
}, "Text size", 8, Ze), f(n, {
|
|
374
|
+
}, "Text size", 8, Ze), f(n, {
|
|
375
|
+
display: "labels",
|
|
376
|
+
block: ""
|
|
377
|
+
})], 8, Xe)) : c("", !0),
|
|
374
378
|
u("div", Qe, [
|
|
375
379
|
(g(!0), l(i, null, v(p.items, (e) => (g(), s(b(q(e)), ne({ key: e.label }, { ref_for: !0 }, st(e), {
|
|
376
380
|
role: "menuitem",
|