@fragment-build/ui 3.3.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.
- package/components/code-snippet/CodeSnippet.d.ts +9 -0
- package/components/code-snippet/CodeSnippet.js +14 -4
- package/components/code-snippet/CodeSnippet.js.map +1 -1
- package/components/code-snippet/code-snippet.css +18 -0
- package/components/segmented-control/SegmentedControl.d.ts +16 -0
- package/components/segmented-control/SegmentedControl.js +18 -0
- package/components/segmented-control/SegmentedControl.js.map +1 -0
- package/components/segmented-control/SegmentedControl.styles.d.ts +46 -0
- package/components/segmented-control/SegmentedControl.styles.js +20 -0
- package/components/segmented-control/SegmentedControl.styles.js.map +1 -0
- package/components/segmented-control/segmented-control.css +41 -0
- package/fragments/empty-state/EmptyState.d.ts +12 -0
- package/fragments/empty-state/EmptyState.js +12 -0
- package/fragments/empty-state/EmptyState.js.map +1 -0
- package/fragments/empty-state/EmptyState.styles.d.ts +55 -0
- package/fragments/empty-state/EmptyState.styles.js +23 -0
- package/fragments/empty-state/EmptyState.styles.js.map +1 -0
- package/fragments/empty-state/empty-state.css +39 -0
- package/fragments/form/FormCard.d.ts +14 -0
- package/fragments/form/FormCard.js +14 -0
- package/fragments/form/FormCard.js.map +1 -0
- package/fragments/form/FormCard.styles.d.ts +49 -0
- package/fragments/form/FormCard.styles.js +23 -0
- package/fragments/form/FormCard.styles.js.map +1 -0
- package/fragments/form/FormSection.d.ts +3 -1
- package/fragments/form/FormSection.js +2 -2
- package/fragments/form/FormSection.js.map +1 -1
- package/fragments/form/FormSection.styles.d.ts +6 -0
- package/fragments/form/FormSection.styles.js +2 -0
- package/fragments/form/FormSection.styles.js.map +1 -1
- package/fragments/form/form-card.css +42 -0
- package/fragments/form/form-section.css +22 -10
- package/fragments/form/form.css +1 -1
- package/fragments/page/PageHeader.d.ts +7 -2
- package/fragments/page/PageHeader.js +3 -3
- package/fragments/page/PageHeader.js.map +1 -1
- package/fragments/page/PageHeader.styles.d.ts +30 -21
- package/fragments/page/PageHeader.styles.js +10 -0
- package/fragments/page/PageHeader.styles.js.map +1 -1
- package/fragments/page/page-header.css +23 -3
- package/fragments/save-bar/SaveBar.d.ts +12 -0
- package/fragments/save-bar/SaveBar.js +15 -0
- package/fragments/save-bar/SaveBar.js.map +1 -0
- package/fragments/save-bar/SaveBar.styles.d.ts +37 -0
- package/fragments/save-bar/SaveBar.styles.js +16 -0
- package/fragments/save-bar/SaveBar.styles.js.map +1 -0
- package/fragments/save-bar/save-bar.css +28 -0
- package/fragments/shell/shell.css +8 -4
- package/fragments/sidebar/Sidebar.js +4 -1
- package/fragments/sidebar/Sidebar.js.map +1 -1
- package/fragments/sidebar/sidebar.css +41 -24
- package/fragments/stat/StatCard.d.ts +29 -0
- package/fragments/stat/StatCard.js +20 -0
- package/fragments/stat/StatCard.js.map +1 -0
- package/fragments/stat/StatCard.styles.d.ts +85 -0
- package/fragments/stat/StatCard.styles.js +26 -0
- package/fragments/stat/StatCard.styles.js.map +1 -0
- package/fragments/stat/stat-card.css +64 -0
- package/fragments/widget/Widget.d.ts +9 -2
- package/fragments/widget/Widget.js +4 -3
- package/fragments/widget/Widget.js.map +1 -1
- package/fragments/widget/Widget.styles.d.ts +51 -0
- package/fragments/widget/Widget.styles.js +12 -0
- package/fragments/widget/Widget.styles.js.map +1 -1
- package/fragments/widget/widget.css +49 -4
- package/index.css +112 -38
- package/index.d.ts +5 -0
- package/index.js +5 -0
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/code-snippet/code-snippet.css +18 -0
- package/src/components/segmented-control/segmented-control.css +41 -0
- package/src/fragments/empty-state/empty-state.css +39 -0
- package/src/fragments/form/form-card.css +42 -0
- package/src/fragments/form/form-section.css +22 -10
- package/src/fragments/form/form.css +1 -1
- package/src/fragments/page/page-header.css +23 -3
- package/src/fragments/save-bar/save-bar.css +28 -0
- package/src/fragments/shell/shell.css +8 -4
- package/src/fragments/sidebar/sidebar.css +41 -24
- package/src/fragments/stat/stat-card.css +64 -0
- package/src/fragments/widget/widget.css +49 -4
- package/src/index.css +112 -38
package/index.d.ts
CHANGED
|
@@ -4,10 +4,15 @@ export { CodeSnippet, type CodeSnippetProps } from './components/code-snippet/Co
|
|
|
4
4
|
export { Grid, type GridProps } from './components/grid/Grid';
|
|
5
5
|
export { MultiSwitch, type MultiSwitchProps } from './components/multi-switch/MultiSwitch';
|
|
6
6
|
export { ThemeSwitch, type ThemeSwitchProps } from './components/theme-switch/ThemeSwitch';
|
|
7
|
+
export { SegmentedControl, type SegmentedControlProps, type SegmentedControlOption, } from './components/segmented-control/SegmentedControl';
|
|
7
8
|
export { Form, type FormProps } from './fragments/form/Form';
|
|
8
9
|
export { FormSection, type FormSectionProps } from './fragments/form/FormSection';
|
|
10
|
+
export { FormCard, type FormCardProps } from './fragments/form/FormCard';
|
|
11
|
+
export { SaveBar, type SaveBarProps } from './fragments/save-bar/SaveBar';
|
|
9
12
|
export { PageHeader, type PageHeaderProps } from './fragments/page/PageHeader';
|
|
10
13
|
export { Navbar, type NavbarProps } from './fragments/navbar/Navbar';
|
|
11
14
|
export { Shell, type ShellProps } from './fragments/shell/Shell';
|
|
12
15
|
export { Sidebar, type SidebarProps } from './fragments/sidebar/Sidebar';
|
|
13
16
|
export { Widget, type WidgetProps } from './fragments/widget/Widget';
|
|
17
|
+
export { StatCard, type StatCardProps, type StatCardDelta } from './fragments/stat/StatCard';
|
|
18
|
+
export { EmptyState, type EmptyStateProps } from './fragments/empty-state/EmptyState';
|
package/index.js
CHANGED
|
@@ -6,11 +6,16 @@ export { CodeSnippet } from './components/code-snippet/CodeSnippet';
|
|
|
6
6
|
export { Grid } from './components/grid/Grid';
|
|
7
7
|
export { MultiSwitch } from './components/multi-switch/MultiSwitch';
|
|
8
8
|
export { ThemeSwitch } from './components/theme-switch/ThemeSwitch';
|
|
9
|
+
export { SegmentedControl, } from './components/segmented-control/SegmentedControl';
|
|
9
10
|
export { Form } from './fragments/form/Form';
|
|
10
11
|
export { FormSection } from './fragments/form/FormSection';
|
|
12
|
+
export { FormCard } from './fragments/form/FormCard';
|
|
13
|
+
export { SaveBar } from './fragments/save-bar/SaveBar';
|
|
11
14
|
export { PageHeader } from './fragments/page/PageHeader';
|
|
12
15
|
export { Navbar } from './fragments/navbar/Navbar';
|
|
13
16
|
export { Shell } from './fragments/shell/Shell';
|
|
14
17
|
export { Sidebar } from './fragments/sidebar/Sidebar';
|
|
15
18
|
export { Widget } from './fragments/widget/Widget';
|
|
19
|
+
export { StatCard } from './fragments/stat/StatCard';
|
|
20
|
+
export { EmptyState } from './fragments/empty-state/EmptyState';
|
|
16
21
|
//# sourceMappingURL=index.js.map
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,sBAAsB;AACtB,OAAO,EAAE,IAAI,EAAkB,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAyB,MAAM,uCAAuC,CAAC;AAC3F,OAAO,EAAE,IAAI,EAAkB,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAyB,MAAM,uCAAuC,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAyB,MAAO,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,sBAAsB;AACtB,OAAO,EAAE,IAAI,EAAkB,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAyB,MAAM,uCAAuC,CAAC;AAC3F,OAAO,EAAE,IAAI,EAAkB,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAyB,MAAM,uCAAuC,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAyB,MAAO,uCAAuC,CAAC;AAC5F,OAAO,EACL,gBAAgB,GACjB,MAAM,iDAAiD,CAAC;AAEzD,OAAO,EAAE,IAAI,EAAkB,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAyB,MAAM,8BAA8B,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAsB,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,OAAO,EAAqB,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAwB,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,MAAM,EAAoB,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,KAAK,EAAmB,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAqB,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,MAAM,EAAoB,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,QAAQ,EAA0C,MAAM,2BAA2B,CAAC;AAC7F,OAAO,EAAE,UAAU,EAAwB,MAAM,oCAAoC,CAAC"}
|
package/package.json
CHANGED
|
@@ -11,3 +11,21 @@
|
|
|
11
11
|
@apply text-muted;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
@layer components {
|
|
16
|
+
.fragment-code-snippet--block {
|
|
17
|
+
@apply overflow-hidden rounded-xl border border-border bg-surface-secondary;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.fragment-code-snippet__header {
|
|
21
|
+
@apply flex items-center justify-between gap-2 border-b border-border py-1 pr-1 pl-4;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.fragment-code-snippet__title {
|
|
25
|
+
@apply text-xs font-medium text-muted;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.fragment-code-snippet__block-code {
|
|
29
|
+
@apply overflow-x-auto px-4 py-3 font-mono text-xs leading-relaxed text-foreground;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.fragment-segmented-control {
|
|
3
|
+
@apply inline-flex items-center gap-0.5 rounded-[var(--field-radius)] bg-default p-0.5;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.fragment-segmented-control--full-width {
|
|
7
|
+
@apply flex w-full;
|
|
8
|
+
|
|
9
|
+
.fragment-segmented-control__item {
|
|
10
|
+
@apply flex-1;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.fragment-segmented-control__item.toggle-button {
|
|
15
|
+
@apply h-8 rounded-[calc(var(--field-radius)-0.125rem)] px-3 text-sm font-medium text-muted md:h-8;
|
|
16
|
+
|
|
17
|
+
--toggle-button-bg: transparent;
|
|
18
|
+
--toggle-button-bg-hover: transparent;
|
|
19
|
+
--toggle-button-bg-pressed: transparent;
|
|
20
|
+
--toggle-button-bg-selected: var(--surface);
|
|
21
|
+
--toggle-button-bg-selected-hover: var(--surface);
|
|
22
|
+
--toggle-button-bg-selected-pressed: var(--surface);
|
|
23
|
+
--toggle-button-fg-selected: var(--surface-foreground, var(--foreground));
|
|
24
|
+
|
|
25
|
+
&:hover, &[data-hovered="true"] {
|
|
26
|
+
@apply text-foreground;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&[data-selected="true"] {
|
|
30
|
+
@apply shadow-sm text-foreground;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
& svg {
|
|
34
|
+
@apply size-4;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.fragment-segmented-control--sm .fragment-segmented-control__item.toggle-button {
|
|
39
|
+
@apply h-7 px-2.5 text-xs md:h-7;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.fragment-empty-state {
|
|
3
|
+
@apply flex flex-col items-center justify-center text-center px-6 py-12;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.fragment-empty-state--sm {
|
|
7
|
+
@apply py-8;
|
|
8
|
+
|
|
9
|
+
.fragment-empty-state__icon {
|
|
10
|
+
@apply size-9 mb-3;
|
|
11
|
+
& svg {
|
|
12
|
+
@apply size-[18px];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.fragment-empty-state--bordered {
|
|
18
|
+
@apply rounded-2xl border border-dashed border-border bg-surface;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.fragment-empty-state__icon {
|
|
22
|
+
@apply mb-4 flex size-11 items-center justify-center rounded-xl bg-default text-muted;
|
|
23
|
+
& svg {
|
|
24
|
+
@apply size-5;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.fragment-empty-state__title {
|
|
29
|
+
@apply text-sm font-semibold text-foreground;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.fragment-empty-state__description {
|
|
33
|
+
@apply mt-1 max-w-sm text-sm text-muted text-balance;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.fragment-empty-state__actions {
|
|
37
|
+
@apply mt-5 flex flex-wrap items-center justify-center gap-2;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.fragment-form-card {
|
|
3
|
+
@apply p-0 gap-0 overflow-visible;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.fragment-form-card__header {
|
|
7
|
+
@apply flex items-start gap-4 px-6 pt-5;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.fragment-form-card__heading {
|
|
11
|
+
@apply min-w-0 flex-1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.fragment-form-card__title {
|
|
15
|
+
@apply text-base font-semibold;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.fragment-form-card__description {
|
|
19
|
+
@apply mt-1 text-sm text-muted;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.fragment-form-card__header-end {
|
|
23
|
+
@apply shrink-0 flex items-center gap-2;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.fragment-form-card__body {
|
|
27
|
+
@apply flex flex-col gap-5 px-6 pt-5 pb-6;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.fragment-form-card__footer {
|
|
31
|
+
@apply flex items-center justify-between gap-3 rounded-b-[inherit] border-t border-separator bg-surface-secondary px-6 py-3
|
|
32
|
+
text-xs text-muted;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.fragment-form-card--danger {
|
|
36
|
+
@apply border-danger/30;
|
|
37
|
+
|
|
38
|
+
.fragment-form-card__title {
|
|
39
|
+
@apply text-danger;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -1,41 +1,53 @@
|
|
|
1
1
|
@layer components {
|
|
2
2
|
.fragment-form-section__main {
|
|
3
|
-
@apply flex flex-col;
|
|
3
|
+
@apply flex flex-col gap-4;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
.fragment-form-section__info {
|
|
7
|
-
@apply
|
|
7
|
+
@apply min-w-0;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
.fragment-form-
|
|
11
|
-
@apply flex
|
|
10
|
+
.fragment-form-section__title-row {
|
|
11
|
+
@apply flex items-center gap-2;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.fragment-form-section__title {
|
|
15
|
+
@apply text-sm font-semibold;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
.fragment-form-section__description {
|
|
15
|
-
@apply text-sm text-muted;
|
|
19
|
+
@apply mt-1 text-sm text-muted;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.fragment-form-section__content {
|
|
23
|
+
@apply flex flex-col gap-5 flex-1 min-w-0;
|
|
16
24
|
}
|
|
17
25
|
|
|
26
|
+
/*
|
|
27
|
+
* Label column and control column. The label column is narrow and fixed so that, down a long
|
|
28
|
+
* settings page, every control starts on the same vertical line.
|
|
29
|
+
*/
|
|
18
30
|
.fragment-form-section--horizontal {
|
|
19
31
|
.fragment-form-section__main {
|
|
20
|
-
@apply
|
|
32
|
+
@apply md:flex-row md:gap-10;
|
|
21
33
|
}
|
|
22
34
|
.fragment-form-section__info {
|
|
23
|
-
@apply
|
|
35
|
+
@apply md:w-72 md:shrink-0;
|
|
24
36
|
}
|
|
25
37
|
.fragment-form-section__content {
|
|
26
|
-
@apply
|
|
38
|
+
@apply md:max-w-xl;
|
|
27
39
|
}
|
|
28
40
|
}
|
|
29
41
|
|
|
30
42
|
.fragment-form-section--vertical {
|
|
31
43
|
.fragment-form-section__content {
|
|
32
|
-
@apply
|
|
44
|
+
@apply md:max-w-3xl;
|
|
33
45
|
}
|
|
34
46
|
}
|
|
35
47
|
|
|
36
48
|
.fragment-form-section--full-width {
|
|
37
49
|
.fragment-form-section__content {
|
|
38
|
-
@apply
|
|
50
|
+
@apply md:max-w-full;
|
|
39
51
|
}
|
|
40
52
|
}
|
|
41
53
|
}
|
|
@@ -1,13 +1,33 @@
|
|
|
1
1
|
@layer components {
|
|
2
2
|
.fragment-page-header {
|
|
3
|
-
@apply flex
|
|
3
|
+
@apply flex flex-col gap-5 mb-8;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.fragment-page-header--with-footer {
|
|
7
|
+
@apply mb-6;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.fragment-page-header__row {
|
|
11
|
+
@apply flex gap-4 justify-between flex-col sm:flex-row sm:items-end;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.fragment-page-header__heading {
|
|
15
|
+
@apply min-w-0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.fragment-page-header__eyebrow {
|
|
19
|
+
@apply mb-1.5 flex items-center gap-1.5 text-xs font-medium text-muted;
|
|
4
20
|
}
|
|
5
21
|
|
|
6
22
|
.fragment-page-header__description {
|
|
7
|
-
@apply mt-
|
|
23
|
+
@apply mt-1 max-w-2xl text-sm text-muted;
|
|
8
24
|
}
|
|
9
25
|
|
|
10
26
|
.fragment-page-header__actions {
|
|
11
|
-
@apply flex gap-
|
|
27
|
+
@apply flex flex-wrap gap-2 items-center shrink-0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.fragment-page-header__footer {
|
|
31
|
+
@apply min-w-0;
|
|
12
32
|
}
|
|
13
33
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
/* Sticky inside the form rather than fixed to the viewport, so it never needs to know how wide the rail is. */
|
|
3
|
+
/* Takes no room while hidden, so a clean form ends where its last field does. */
|
|
4
|
+
.fragment-save-bar {
|
|
5
|
+
@apply pointer-events-none sticky bottom-20 z-30 flex h-0 justify-center overflow-visible md:bottom-6;
|
|
6
|
+
@apply translate-y-4 opacity-0 transition-[opacity,translate] duration-200 motion-reduce:transition-none;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.fragment-save-bar--visible {
|
|
10
|
+
@apply pointer-events-auto mt-6 h-auto translate-y-0 opacity-100;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.fragment-save-bar__bar {
|
|
14
|
+
@apply flex w-full max-w-2xl items-center justify-between gap-4 rounded-2xl border border-border bg-overlay py-2 pr-2 pl-4
|
|
15
|
+
text-sm shadow-lg;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.fragment-save-bar__message {
|
|
19
|
+
@apply flex items-center gap-2 font-medium text-foreground;
|
|
20
|
+
& svg {
|
|
21
|
+
@apply shrink-0 text-warning;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.fragment-save-bar__actions {
|
|
26
|
+
@apply flex shrink-0 items-center gap-1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -7,16 +7,20 @@
|
|
|
7
7
|
@apply flex-col;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/*
|
|
11
|
+
* The content column is capped at a width a table or a two-column dashboard still reads well at.
|
|
12
|
+
* Past ~1600px the eye travels too far between a label and its value, and a wide monitor is
|
|
13
|
+
* better spent on margin than on stretching every card.
|
|
14
|
+
*/
|
|
10
15
|
.fragment-shell__main {
|
|
11
|
-
@apply flex-1 min-w-0 mx-auto;
|
|
16
|
+
@apply flex-1 min-w-0 mx-auto w-full;
|
|
12
17
|
|
|
13
18
|
.fragment-shell--horizontal & {
|
|
14
|
-
@apply px-
|
|
19
|
+
@apply px-4 sm:px-6 lg:px-10 pt-6 pb-24 md:pt-8 md:pb-12 max-w-[1600px];
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
.fragment-shell--vertical & {
|
|
18
|
-
@apply px-
|
|
23
|
+
@apply px-4 sm:px-6 lg:px-10 py-6 max-w-[1600px];
|
|
19
24
|
}
|
|
20
|
-
|
|
21
25
|
}
|
|
22
26
|
}
|
|
@@ -5,28 +5,29 @@
|
|
|
5
5
|
|
|
6
6
|
.fragment-sidebar__collapsed {
|
|
7
7
|
@apply fixed top-0 left-0 border-r border-border bg-sidebar text-sidebar-foreground
|
|
8
|
-
flex flex-col h-screen gap-
|
|
8
|
+
flex flex-col h-screen gap-4 transition-all z-40;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
.fragment-sidebar__collapsed-body {
|
|
12
|
-
@apply w-
|
|
12
|
+
@apply w-16 items-center flex flex-col gap-6 px-2 pt-5 overflow-y-auto flex-1;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
.fragment-sidebar__collapsed-footer {
|
|
16
|
-
@apply w-
|
|
16
|
+
@apply w-16 items-center flex flex-col gap-3 px-2 pb-4;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
.fragment-sidebar__expanded {
|
|
20
20
|
@apply fixed top-0 left-0 border-r border-border bg-sidebar text-sidebar-foreground
|
|
21
|
-
flex flex-col h-screen gap-
|
|
21
|
+
flex flex-col h-screen gap-4 overflow-hidden transition-all z-40;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
.fragment-sidebar__expanded-body {
|
|
25
|
-
@apply w-
|
|
25
|
+
@apply w-64 flex flex-col gap-6 px-3 pt-5 overflow-y-auto flex-1;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
/* The footer is chrome (account, workspace), so it is tucked behind a hairline. */
|
|
28
29
|
.fragment-sidebar__expanded-footer {
|
|
29
|
-
@apply w-
|
|
30
|
+
@apply w-64 flex flex-col gap-2 px-3 pt-3 pb-4 border-t border-border;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
.fragment-sidebar__placeholder {
|
|
@@ -34,11 +35,14 @@
|
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
.fragment-sidebar__layout-button-wrapper {
|
|
37
|
-
@apply fixed top-6 transition-all;
|
|
38
|
+
@apply fixed top-6 transition-all z-50;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
.fragment-sidebar__layout-button {
|
|
41
|
-
@apply h-6! w-6
|
|
42
|
+
@apply h-6! w-6! min-w-6! bg-surface! border border-border shadow-sm text-muted;
|
|
43
|
+
& svg {
|
|
44
|
+
@apply size-3.5;
|
|
45
|
+
}
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
.fragment-sidebar__bottom-nav {
|
|
@@ -69,7 +73,7 @@
|
|
|
69
73
|
.fragment-sidebar__collapsed-nav {
|
|
70
74
|
@apply flex flex-col gap-1;
|
|
71
75
|
& svg {
|
|
72
|
-
@apply size-
|
|
76
|
+
@apply size-[18px]! shrink-0 self-center;
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
|
|
@@ -106,23 +110,36 @@
|
|
|
106
110
|
}
|
|
107
111
|
|
|
108
112
|
.fragment-sidebar__custom-item {
|
|
109
|
-
@apply px-
|
|
113
|
+
@apply px-1;
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
.fragment-sidebar__nav {
|
|
113
|
-
@apply text-sm;
|
|
117
|
+
@apply text-sm flex flex-col gap-0.5;
|
|
118
|
+
|
|
119
|
+
/* Group label: quiet, so it organises the list without competing with it. */
|
|
120
|
+
& > .header {
|
|
121
|
+
@apply px-3 pb-1 text-xs font-medium text-muted;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.list-box {
|
|
125
|
+
@apply gap-0.5;
|
|
126
|
+
}
|
|
114
127
|
|
|
115
128
|
.list-box-item {
|
|
116
|
-
@apply px-3! pr-1! py-1! h-
|
|
129
|
+
@apply px-3! pr-1! py-1! h-9! gap-3! rounded-lg! font-normal text-sidebar-foreground/80;
|
|
130
|
+
&:hover, &[data-hovered="true"] {
|
|
131
|
+
background-color: var(--sidebar-default, var(--default)) !important;
|
|
132
|
+
@apply text-sidebar-foreground;
|
|
133
|
+
}
|
|
117
134
|
}
|
|
118
135
|
|
|
119
136
|
& svg {
|
|
120
|
-
@apply size-
|
|
137
|
+
@apply size-[18px] shrink-0 self-center;
|
|
121
138
|
}
|
|
122
139
|
}
|
|
123
140
|
|
|
124
141
|
.fragment-sidebar__accordion-trigger {
|
|
125
|
-
@apply w-full flex items-center gap-3 h-
|
|
142
|
+
@apply w-full flex items-center gap-3 h-9 px-3 pr-1 py-1 rounded-lg text-sm font-normal cursor-pointer
|
|
126
143
|
text-sidebar-foreground transition-colors;
|
|
127
144
|
&:hover, &[data-hovered="true"] {
|
|
128
145
|
/* `--default` is a page-level palette colour; opt out per-rail with `--sidebar-default`. */
|
|
@@ -161,7 +178,7 @@
|
|
|
161
178
|
|
|
162
179
|
.fragment-sidebar__nav-item--active {
|
|
163
180
|
/* `--accent-soft` is translucent, so it composites over the rail, not the page. */
|
|
164
|
-
@apply bg-accent-soft!;
|
|
181
|
+
@apply bg-accent-soft! font-medium!;
|
|
165
182
|
color: var(--sidebar-accent-soft-foreground, var(--accent-soft-foreground)) !important;
|
|
166
183
|
}
|
|
167
184
|
|
|
@@ -180,13 +197,13 @@
|
|
|
180
197
|
/* Layout modifier variants */
|
|
181
198
|
.fragment-sidebar--auto {
|
|
182
199
|
.fragment-sidebar__expanded {
|
|
183
|
-
@apply w-
|
|
200
|
+
@apply w-16 opacity-0 pointer-events-none xl:w-64 xl:opacity-100 xl:pointer-events-auto;
|
|
184
201
|
}
|
|
185
202
|
.fragment-sidebar__placeholder {
|
|
186
|
-
@apply w-
|
|
203
|
+
@apply w-16 opacity-0 pointer-events-none xl:w-64 xl:opacity-100 xl:pointer-events-auto;
|
|
187
204
|
}
|
|
188
205
|
.fragment-sidebar__layout-button-wrapper {
|
|
189
|
-
@apply left-
|
|
206
|
+
@apply left-16 translate-x-1/2 rotate-180 xl:left-64 xl:-translate-x-1/2 xl:rotate-0;
|
|
190
207
|
}
|
|
191
208
|
.fragment-sidebar__collapsed {
|
|
192
209
|
@apply xl:opacity-0;
|
|
@@ -195,13 +212,13 @@
|
|
|
195
212
|
|
|
196
213
|
.fragment-sidebar--collapsed {
|
|
197
214
|
.fragment-sidebar__expanded {
|
|
198
|
-
@apply w-
|
|
215
|
+
@apply w-16 opacity-0 pointer-events-none;
|
|
199
216
|
}
|
|
200
217
|
.fragment-sidebar__placeholder {
|
|
201
|
-
@apply w-
|
|
218
|
+
@apply w-16 opacity-0 pointer-events-none;
|
|
202
219
|
}
|
|
203
220
|
.fragment-sidebar__layout-button-wrapper {
|
|
204
|
-
@apply left-
|
|
221
|
+
@apply left-16 translate-x-1/2 rotate-180;
|
|
205
222
|
}
|
|
206
223
|
}
|
|
207
224
|
|
|
@@ -210,13 +227,13 @@
|
|
|
210
227
|
@apply opacity-0;
|
|
211
228
|
}
|
|
212
229
|
.fragment-sidebar__expanded {
|
|
213
|
-
@apply w-
|
|
230
|
+
@apply w-64;
|
|
214
231
|
}
|
|
215
232
|
.fragment-sidebar__placeholder {
|
|
216
|
-
@apply w-
|
|
233
|
+
@apply w-64;
|
|
217
234
|
}
|
|
218
235
|
.fragment-sidebar__layout-button-wrapper {
|
|
219
|
-
@apply left-
|
|
236
|
+
@apply left-64 -translate-x-1/2;
|
|
220
237
|
}
|
|
221
238
|
}
|
|
222
239
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.fragment-stat-card {
|
|
3
|
+
@apply p-4 gap-2 min-w-0;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.fragment-stat-card__top {
|
|
7
|
+
@apply flex items-center justify-between gap-2;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.fragment-stat-card__label {
|
|
11
|
+
@apply flex items-center gap-1 text-xs font-medium text-muted min-w-0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.fragment-stat-card__help {
|
|
15
|
+
@apply inline-flex text-muted/70 hover:text-foreground cursor-help rounded-full outline-none
|
|
16
|
+
focus-visible:ring-2 focus-visible:ring-focus;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.fragment-stat-card__icon {
|
|
20
|
+
@apply flex size-8 shrink-0 items-center justify-center rounded-lg bg-default text-muted;
|
|
21
|
+
& svg {
|
|
22
|
+
@apply size-4;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.fragment-stat-card__value-row {
|
|
27
|
+
@apply flex flex-wrap items-baseline gap-x-2 gap-y-1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Proportional figures: a standalone number with tabular digits looks loosely set. */
|
|
31
|
+
.fragment-stat-card__value {
|
|
32
|
+
@apply text-2xl font-semibold tracking-tight text-foreground truncate;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.fragment-stat-card__delta {
|
|
36
|
+
@apply inline-flex items-center gap-0.5 rounded-md px-1.5 py-0.5 text-xs font-medium;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.fragment-stat-card__delta--positive {
|
|
40
|
+
@apply bg-success-soft text-success-soft-foreground;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.fragment-stat-card__delta--negative {
|
|
44
|
+
@apply bg-danger-soft text-danger-soft-foreground;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.fragment-stat-card__delta--neutral {
|
|
48
|
+
@apply bg-default text-muted;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.fragment-stat-card__hint {
|
|
52
|
+
@apply text-xs text-muted;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.fragment-stat-card__skeleton {
|
|
56
|
+
@apply h-8 w-24 rounded-lg;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.fragment-stat-card--emphasis {
|
|
60
|
+
.fragment-stat-card__value {
|
|
61
|
+
@apply text-3xl;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -1,18 +1,59 @@
|
|
|
1
1
|
@layer components {
|
|
2
2
|
.fragment-widget {
|
|
3
|
-
@apply
|
|
3
|
+
@apply p-5 gap-4 min-w-0;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
.fragment-widget__header {
|
|
7
|
-
@apply p-0;
|
|
7
|
+
@apply p-0 flex flex-row items-start gap-3;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.fragment-widget__header-start {
|
|
11
|
+
@apply shrink-0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.fragment-widget__heading {
|
|
15
|
+
@apply min-w-0 flex-1;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.fragment-widget__title {
|
|
19
|
+
@apply text-sm font-semibold;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.fragment-widget__description {
|
|
23
|
+
@apply mt-0.5 text-xs text-muted;
|
|
8
24
|
}
|
|
9
25
|
|
|
10
26
|
.fragment-widget__header-end {
|
|
11
|
-
@apply ml-auto;
|
|
27
|
+
@apply ml-auto flex items-center gap-2 shrink-0;
|
|
12
28
|
}
|
|
13
29
|
|
|
14
30
|
.fragment-widget__content {
|
|
15
|
-
@apply p-0 overflow-visible;
|
|
31
|
+
@apply p-0 overflow-visible min-w-0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.fragment-widget__footer {
|
|
35
|
+
@apply -mx-5 -mb-5 mt-auto px-5 py-3 border-t border-separator text-xs text-muted;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.fragment-widget--padding-sm {
|
|
39
|
+
@apply p-4 gap-3;
|
|
40
|
+
|
|
41
|
+
.fragment-widget__footer {
|
|
42
|
+
@apply -mx-4 -mb-4 px-4;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Edge-to-edge content: the header keeps its inset, the body does not. */
|
|
47
|
+
.fragment-widget--flush {
|
|
48
|
+
@apply p-0 gap-0;
|
|
49
|
+
|
|
50
|
+
.fragment-widget__header {
|
|
51
|
+
@apply px-5 pt-5 pb-4;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.fragment-widget__footer {
|
|
55
|
+
@apply mx-0 mb-0;
|
|
56
|
+
}
|
|
16
57
|
}
|
|
17
58
|
|
|
18
59
|
.fragment-widget--sm {
|
|
@@ -26,4 +67,8 @@
|
|
|
26
67
|
.fragment-widget--lg {
|
|
27
68
|
@apply col-span-1 lg:col-span-2 2xl:col-span-3;
|
|
28
69
|
}
|
|
70
|
+
|
|
71
|
+
.fragment-widget--full {
|
|
72
|
+
@apply col-span-full;
|
|
73
|
+
}
|
|
29
74
|
}
|