@marianmeres/stuic 3.48.0 → 3.51.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/AGENTS.md +3 -4
- package/API.md +5 -16
- package/dist/actions/dim-behind/index.css +1 -2
- package/dist/actions/onboarding/index.css +1 -2
- package/dist/components/Accordion/index.css +6 -9
- package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte +1 -1
- package/dist/components/AssetsPreview/index.css +3 -5
- package/dist/components/Avatar/index.css +3 -4
- package/dist/components/Book/index.css +3 -4
- package/dist/components/Button/index.css +11 -13
- package/dist/components/ButtonGroupRadio/index.css +5 -8
- package/dist/components/Card/Card.svelte +168 -0
- package/dist/components/Card/Card.svelte.d.ts +54 -0
- package/dist/components/Card/README.md +120 -0
- package/dist/components/Card/index.css +184 -0
- package/dist/components/Card/index.d.ts +1 -0
- package/dist/components/Card/index.js +1 -0
- package/dist/components/Carousel/index.css +5 -8
- package/dist/components/Cart/index.css +6 -8
- package/dist/components/Collapsible/index.css +1 -2
- package/dist/components/CommandMenu/index.css +0 -1
- package/dist/components/DataTable/index.css +11 -15
- package/dist/components/DismissibleMessage/index.css +4 -7
- package/dist/components/DropdownMenu/index.css +4 -6
- package/dist/components/IconSwap/index.css +1 -2
- package/dist/components/Input/index.css +19 -22
- package/dist/components/KbdShortcut/index.css +2 -4
- package/dist/components/ListItemButton/index.css +4 -6
- package/dist/components/Modal/index.css +1 -2
- package/dist/components/ModalDialog/index.css +3 -6
- package/dist/components/Nav/index.css +4 -6
- package/dist/components/Notifications/index.css +9 -12
- package/dist/components/Progress/index.css +1 -2
- package/dist/components/Skeleton/index.css +1 -2
- package/dist/components/TabbedMenu/index.css +2 -3
- package/dist/components/ThemePreview/index.css +13 -13
- package/dist/components/Tree/index.css +3 -5
- package/dist/components/WithSidePanel/index.css +2 -3
- package/dist/components/X/index.css +1 -2
- package/dist/index.css +26 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/mcp.js +1 -1
- package/dist/themes/css/blue-orange.css +132 -132
- package/dist/themes/css/cyan-red.css +132 -132
- package/dist/themes/css/cyan-slate.css +132 -132
- package/dist/themes/css/emerald-amber-forest.css +132 -132
- package/dist/themes/css/emerald-pink.css +132 -132
- package/dist/themes/css/fuchsia-emerald.css +132 -132
- package/dist/themes/css/gray.css +132 -132
- package/dist/themes/css/indigo-amber.css +132 -132
- package/dist/themes/css/lime-fuchsia-neon.css +132 -132
- package/dist/themes/css/monokai-cyan.css +132 -132
- package/dist/themes/css/monokai-green.css +132 -132
- package/dist/themes/css/monokai-pink.css +132 -132
- package/dist/themes/css/orange-pink-sunset.css +132 -132
- package/dist/themes/css/pink-emerald.css +132 -132
- package/dist/themes/css/pink-teal.css +132 -132
- package/dist/themes/css/purple-yellow.css +132 -132
- package/dist/themes/css/rainbow.css +132 -132
- package/dist/themes/css/red-blue.css +132 -132
- package/dist/themes/css/red-cyan.css +132 -132
- package/dist/themes/css/red-sky-slate.css +132 -132
- package/dist/themes/css/red-sky.css +132 -132
- package/dist/themes/css/rose-teal.css +132 -132
- package/dist/themes/css/sky-amber.css +132 -132
- package/dist/themes/css/slate-cyan.css +132 -132
- package/dist/themes/css/slate-teal-ocean.css +132 -132
- package/dist/themes/css/stone-orange-earth.css +132 -132
- package/dist/themes/css/stone.css +132 -132
- package/dist/themes/css/teal-rose.css +132 -132
- package/dist/themes/css/violet-lime.css +132 -132
- package/dist/themes/css/violet-rose-dusk.css +132 -132
- package/dist/themes/css/zinc.css +132 -132
- package/dist/utils/design-tokens.d.ts +2 -47
- package/dist/utils/design-tokens.js +2 -204
- package/docs/domains/theming.md +9 -10
- package/docs/domains/utils.md +2 -2
- package/package.json +3 -6
- package/dist/themes/blue-orange.d.ts +0 -6
- package/dist/themes/blue-orange.js +0 -115
- package/dist/themes/css/dds.css +0 -217
- package/dist/themes/cyan-red.d.ts +0 -6
- package/dist/themes/cyan-red.js +0 -115
- package/dist/themes/cyan-slate.d.ts +0 -6
- package/dist/themes/cyan-slate.js +0 -115
- package/dist/themes/dds.d.ts +0 -6
- package/dist/themes/dds.js +0 -134
- package/dist/themes/emerald-amber-forest.d.ts +0 -6
- package/dist/themes/emerald-amber-forest.js +0 -115
- package/dist/themes/emerald-pink.d.ts +0 -6
- package/dist/themes/emerald-pink.js +0 -115
- package/dist/themes/fuchsia-emerald.d.ts +0 -6
- package/dist/themes/fuchsia-emerald.js +0 -115
- package/dist/themes/gray.d.ts +0 -6
- package/dist/themes/gray.js +0 -115
- package/dist/themes/indigo-amber.d.ts +0 -6
- package/dist/themes/indigo-amber.js +0 -115
- package/dist/themes/lime-fuchsia-neon.d.ts +0 -6
- package/dist/themes/lime-fuchsia-neon.js +0 -115
- package/dist/themes/monokai-cyan.d.ts +0 -6
- package/dist/themes/monokai-cyan.js +0 -117
- package/dist/themes/monokai-green.d.ts +0 -6
- package/dist/themes/monokai-green.js +0 -117
- package/dist/themes/monokai-pink.d.ts +0 -6
- package/dist/themes/monokai-pink.js +0 -117
- package/dist/themes/orange-pink-sunset.d.ts +0 -6
- package/dist/themes/orange-pink-sunset.js +0 -115
- package/dist/themes/pink-emerald.d.ts +0 -6
- package/dist/themes/pink-emerald.js +0 -115
- package/dist/themes/pink-teal.d.ts +0 -6
- package/dist/themes/pink-teal.js +0 -115
- package/dist/themes/purple-yellow.d.ts +0 -6
- package/dist/themes/purple-yellow.js +0 -115
- package/dist/themes/rainbow.d.ts +0 -6
- package/dist/themes/rainbow.js +0 -120
- package/dist/themes/red-blue.d.ts +0 -6
- package/dist/themes/red-blue.js +0 -115
- package/dist/themes/red-cyan.d.ts +0 -6
- package/dist/themes/red-cyan.js +0 -115
- package/dist/themes/red-sky-slate.d.ts +0 -6
- package/dist/themes/red-sky-slate.js +0 -115
- package/dist/themes/red-sky.d.ts +0 -6
- package/dist/themes/red-sky.js +0 -115
- package/dist/themes/rose-teal.d.ts +0 -6
- package/dist/themes/rose-teal.js +0 -115
- package/dist/themes/sky-amber.d.ts +0 -6
- package/dist/themes/sky-amber.js +0 -115
- package/dist/themes/slate-cyan.d.ts +0 -6
- package/dist/themes/slate-cyan.js +0 -115
- package/dist/themes/slate-teal-ocean.d.ts +0 -6
- package/dist/themes/slate-teal-ocean.js +0 -115
- package/dist/themes/stone-orange-earth.d.ts +0 -6
- package/dist/themes/stone-orange-earth.js +0 -115
- package/dist/themes/stone.d.ts +0 -6
- package/dist/themes/stone.js +0 -115
- package/dist/themes/teal-rose.d.ts +0 -6
- package/dist/themes/teal-rose.js +0 -115
- package/dist/themes/violet-lime.d.ts +0 -6
- package/dist/themes/violet-lime.js +0 -115
- package/dist/themes/violet-rose-dusk.d.ts +0 -6
- package/dist/themes/violet-rose-dusk.js +0 -115
- package/dist/themes/zinc.d.ts +0 -6
- package/dist/themes/zinc.js +0 -115
package/AGENTS.md
CHANGED
|
@@ -26,7 +26,7 @@ src/lib/
|
|
|
26
26
|
├── components/ # 46 UI components
|
|
27
27
|
├── actions/ # 15 Svelte actions
|
|
28
28
|
├── utils/ # 43 utility modules
|
|
29
|
-
├── themes/ #
|
|
29
|
+
├── themes/ # Generated theme CSS (css/) — definitions from @marianmeres/design-tokens
|
|
30
30
|
├── icons/ # Icon re-exports
|
|
31
31
|
├── index.css # Centralized CSS imports
|
|
32
32
|
└── index.ts # Main exports
|
|
@@ -92,9 +92,8 @@ src/lib/
|
|
|
92
92
|
| -------------------------------- | ---------------------------------------------------------------------- |
|
|
93
93
|
| `src/lib/index.css` | CSS entry point |
|
|
94
94
|
| `src/lib/index.ts` | JS entry point |
|
|
95
|
-
| `src/lib/utils/design-tokens.ts` |
|
|
96
|
-
| `src/lib/themes
|
|
97
|
-
| `src/lib/themes/css/stone.css` | Default theme (generated) |
|
|
95
|
+
| `src/lib/utils/design-tokens.ts` | Re-exports from `@marianmeres/design-tokens` |
|
|
96
|
+
| `src/lib/themes/css/stone.css` | Default theme (generated from `@marianmeres/design-tokens/themes`) |
|
|
98
97
|
| `src/lib/components/Button/` | Reference component |
|
|
99
98
|
| `scripts/generate-theme.ts` | CLI: `pnpm run build:theme:all` |
|
|
100
99
|
|
package/API.md
CHANGED
|
@@ -1711,17 +1711,6 @@ Format a token record as a CSS selector block.
|
|
|
1711
1711
|
|
|
1712
1712
|
**Returns:** `string` — CSS block string
|
|
1713
1713
|
|
|
1714
|
-
#### `createDarkOverride(baseTokens, overrides)`
|
|
1715
|
-
|
|
1716
|
-
Create a filtered dark mode token set from base tokens and overrides.
|
|
1717
|
-
|
|
1718
|
-
**Parameters:**
|
|
1719
|
-
|
|
1720
|
-
- `baseTokens` (GeneratedTokens) — Light mode tokens (used as key filter)
|
|
1721
|
-
- `overrides` (Partial\<GeneratedTokens\>) — Dark mode values
|
|
1722
|
-
|
|
1723
|
-
**Returns:** `GeneratedTokens`
|
|
1724
|
-
|
|
1725
1714
|
---
|
|
1726
1715
|
|
|
1727
1716
|
## Icons
|
|
@@ -1879,19 +1868,19 @@ Each component defines customization tokens. Override globally in `:root {}` or
|
|
|
1879
1868
|
| property | `bg`, `text`, `border`, `ring`, `shadow`, `radius`, `padding` |
|
|
1880
1869
|
| state | `hover`, `active`, `focus`, `disabled`, `error` |
|
|
1881
1870
|
|
|
1882
|
-
### Available Themes (
|
|
1871
|
+
### Available Themes (31)
|
|
1883
1872
|
|
|
1884
|
-
Default theme: `stone`.
|
|
1873
|
+
Default theme: `stone`. Theme definitions come from `@marianmeres/design-tokens`.
|
|
1885
1874
|
|
|
1886
1875
|
```ts
|
|
1887
1876
|
// Import pre-built CSS
|
|
1888
1877
|
import "@marianmeres/stuic/themes/css/blue-orange.css";
|
|
1889
1878
|
|
|
1890
|
-
// Import theme definition object (
|
|
1891
|
-
import stone from "@marianmeres/
|
|
1879
|
+
// Import theme definition object (from design-tokens package)
|
|
1880
|
+
import { stone } from "@marianmeres/design-tokens/themes";
|
|
1892
1881
|
```
|
|
1893
1882
|
|
|
1894
|
-
stone, gray, zinc,
|
|
1883
|
+
stone, gray, zinc, blue-orange, cyan-red, cyan-slate, emerald-amber-forest, emerald-pink, fuchsia-emerald, indigo-amber, lime-fuchsia-neon, monokai-cyan, monokai-green, monokai-pink, orange-pink-sunset, pink-emerald, pink-teal, purple-yellow, rainbow, red-blue, red-cyan, red-sky, red-sky-slate, rose-teal, sky-amber, slate-cyan, slate-teal-ocean, stone-orange-earth, teal-rose, violet-lime, violet-rose-dusk
|
|
1895
1884
|
|
|
1896
1885
|
### Dark Mode
|
|
1897
1886
|
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
--stuic-dim-behind-backdrop-bg: rgb(0 0 0 / 0.5);
|
|
8
8
|
--stuic-dim-behind-backdrop-z-index: 40;
|
|
9
9
|
--stuic-dim-behind-element-z-index: 41;
|
|
10
|
-
--stuic-dim-behind-transition-duration: 150ms;
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
.stuic-dim-behind-backdrop {
|
|
@@ -17,7 +16,7 @@
|
|
|
17
16
|
background: var(--stuic-dim-behind-backdrop-bg);
|
|
18
17
|
opacity: 0;
|
|
19
18
|
transition-property: opacity;
|
|
20
|
-
transition-duration: var(--stuic-dim-behind-transition-duration);
|
|
19
|
+
transition-duration: var(--stuic-dim-behind-transition-duration, var(--stuic-transition));
|
|
21
20
|
pointer-events: auto;
|
|
22
21
|
|
|
23
22
|
&.dim-visible {
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
--stuic-onboarding-shell-gap: calc(var(--spacing) * 2);
|
|
6
6
|
--stuic-onboarding-shell-min-width: 200px;
|
|
7
7
|
--stuic-onboarding-shell-max-width: 320px;
|
|
8
|
-
--stuic-onboarding-shell-radius: var(--radius-md, 0.375rem);
|
|
9
8
|
--stuic-onboarding-title-size: var(--text-base);
|
|
10
9
|
--stuic-onboarding-content-size: var(--text-sm);
|
|
11
10
|
--stuic-onboarding-footer-gap: calc(var(--spacing) * 3);
|
|
@@ -21,7 +20,7 @@
|
|
|
21
20
|
padding: var(--stuic-onboarding-shell-padding);
|
|
22
21
|
min-width: var(--stuic-onboarding-shell-min-width);
|
|
23
22
|
max-width: var(--stuic-onboarding-shell-max-width);
|
|
24
|
-
border-radius: var(--stuic-onboarding-shell-radius);
|
|
23
|
+
border-radius: var(--stuic-onboarding-shell-radius, var(--stuic-radius));
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
.stuic-onboarding-title {
|
|
@@ -7,11 +7,8 @@
|
|
|
7
7
|
:root {
|
|
8
8
|
/* Border & shape */
|
|
9
9
|
--stuic-accordion-border-color: var(--stuic-color-border);
|
|
10
|
-
--stuic-accordion-border-width: 1px;
|
|
11
|
-
--stuic-accordion-radius: var(--radius-md);
|
|
12
10
|
|
|
13
11
|
/* Animation */
|
|
14
|
-
--stuic-accordion-transition: 200ms;
|
|
15
12
|
|
|
16
13
|
/* Trigger */
|
|
17
14
|
--stuic-accordion-trigger-padding-x: 1rem;
|
|
@@ -39,8 +36,8 @@
|
|
|
39
36
|
============================================================================ */
|
|
40
37
|
|
|
41
38
|
.stuic-accordion {
|
|
42
|
-
border: var(--stuic-accordion-border-width) solid var(--stuic-accordion-border-color);
|
|
43
|
-
border-radius: var(--stuic-accordion-radius);
|
|
39
|
+
border: var(--stuic-accordion-border-width, var(--stuic-border-width)) solid var(--stuic-accordion-border-color);
|
|
40
|
+
border-radius: var(--stuic-accordion-radius, var(--stuic-radius-container));
|
|
44
41
|
overflow: hidden;
|
|
45
42
|
}
|
|
46
43
|
|
|
@@ -49,7 +46,7 @@
|
|
|
49
46
|
============================================================================ */
|
|
50
47
|
|
|
51
48
|
.stuic-accordion-item + .stuic-accordion-item {
|
|
52
|
-
border-top: var(--stuic-accordion-border-width) solid
|
|
49
|
+
border-top: var(--stuic-accordion-border-width, var(--stuic-border-width)) solid
|
|
53
50
|
var(--stuic-accordion-border-color);
|
|
54
51
|
}
|
|
55
52
|
|
|
@@ -69,7 +66,7 @@
|
|
|
69
66
|
border: none;
|
|
70
67
|
cursor: pointer;
|
|
71
68
|
text-align: left;
|
|
72
|
-
transition: background var(--stuic-accordion-transition);
|
|
69
|
+
transition: background var(--stuic-accordion-transition, var(--stuic-transition));
|
|
73
70
|
}
|
|
74
71
|
|
|
75
72
|
.stuic-accordion-trigger:hover:not(:disabled) {
|
|
@@ -92,7 +89,7 @@
|
|
|
92
89
|
|
|
93
90
|
.stuic-accordion-chevron {
|
|
94
91
|
flex-shrink: 0;
|
|
95
|
-
transition: transform var(--stuic-accordion-transition);
|
|
92
|
+
transition: transform var(--stuic-accordion-transition, var(--stuic-transition));
|
|
96
93
|
}
|
|
97
94
|
|
|
98
95
|
[data-open="true"] > .stuic-accordion-trigger > .stuic-accordion-chevron {
|
|
@@ -106,7 +103,7 @@
|
|
|
106
103
|
.stuic-accordion-content {
|
|
107
104
|
display: grid;
|
|
108
105
|
grid-template-rows: 0fr;
|
|
109
|
-
transition: grid-template-rows var(--stuic-accordion-transition);
|
|
106
|
+
transition: grid-template-rows var(--stuic-accordion-transition, var(--stuic-transition));
|
|
110
107
|
}
|
|
111
108
|
|
|
112
109
|
[data-open="true"] > .stuic-accordion-content {
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
noClickOutsideClose
|
|
98
98
|
type={acp?.current?.type}
|
|
99
99
|
class={twMerge(
|
|
100
|
-
"max-w-xl justify-end max-h-[62vh] h-auto border p-4
|
|
100
|
+
"max-w-xl justify-end max-h-[62vh] h-auto border p-4",
|
|
101
101
|
// different max-h based on not/existing content
|
|
102
102
|
// isTHCNotEmpty(acp?.current?.content) ? "sm:max-h-[200px]" : "sm:max-h-[150px]",
|
|
103
103
|
// acp?.current?.type === PROMPT && "sm:max-h-[250px]",
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
/* Labels (filename, tooltip) */
|
|
11
11
|
--stuic-assets-preview-label-bg: rgba(0 0 0 / 0.6);
|
|
12
12
|
--stuic-assets-preview-label-text: white;
|
|
13
|
-
--stuic-assets-preview-label-radius: var(--radius-sm);
|
|
14
13
|
|
|
15
14
|
/* Dot indicators */
|
|
16
15
|
--stuic-assets-preview-dot-size: 0.75rem;
|
|
@@ -27,7 +26,6 @@
|
|
|
27
26
|
--stuic-assets-preview-area-fill-hover: rgba(0 0 0 / 0.06);
|
|
28
27
|
|
|
29
28
|
/* Transition */
|
|
30
|
-
--stuic-assets-preview-transition: 150ms;
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
@layer components {
|
|
@@ -38,7 +36,7 @@
|
|
|
38
36
|
.stuic-assets-preview-label {
|
|
39
37
|
background: var(--stuic-assets-preview-label-bg);
|
|
40
38
|
color: var(--stuic-assets-preview-label-text);
|
|
41
|
-
border-radius: var(--stuic-assets-preview-label-radius);
|
|
39
|
+
border-radius: var(--stuic-assets-preview-label-radius, var(--stuic-radius));
|
|
42
40
|
}
|
|
43
41
|
|
|
44
42
|
/* ============================================================================
|
|
@@ -51,7 +49,7 @@
|
|
|
51
49
|
border-radius: 9999px;
|
|
52
50
|
background: var(--stuic-assets-preview-dot-bg);
|
|
53
51
|
border: 1px solid var(--stuic-assets-preview-dot-border);
|
|
54
|
-
transition: background var(--stuic-assets-preview-transition);
|
|
52
|
+
transition: background var(--stuic-assets-preview-transition, var(--stuic-transition));
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
.stuic-assets-preview-dot:hover {
|
|
@@ -78,7 +76,7 @@
|
|
|
78
76
|
pointer-events: all;
|
|
79
77
|
cursor: pointer;
|
|
80
78
|
fill: transparent;
|
|
81
|
-
transition: fill var(--stuic-assets-preview-transition);
|
|
79
|
+
transition: fill var(--stuic-assets-preview-transition, var(--stuic-transition));
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
.stuic-assets-preview-area:hover {
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
/* Component-level customization tokens */
|
|
9
9
|
--stuic-avatar-radius: 9999px;
|
|
10
10
|
--stuic-avatar-font-weight: var(--font-weight-medium);
|
|
11
|
-
--stuic-avatar-transition: 150ms;
|
|
12
11
|
|
|
13
12
|
/* Default colors (uses muted role colors) */
|
|
14
13
|
--stuic-avatar-bg: var(--stuic-color-muted);
|
|
@@ -65,9 +64,9 @@
|
|
|
65
64
|
|
|
66
65
|
/* Transition for interactive mode */
|
|
67
66
|
transition:
|
|
68
|
-
background var(--stuic-avatar-transition),
|
|
69
|
-
color var(--stuic-avatar-transition),
|
|
70
|
-
opacity var(--stuic-avatar-transition);
|
|
67
|
+
background var(--stuic-avatar-transition, var(--stuic-transition)),
|
|
68
|
+
color var(--stuic-avatar-transition, var(--stuic-transition)),
|
|
69
|
+
opacity var(--stuic-avatar-transition, var(--stuic-transition));
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
/* ============================================================================
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
--stuic-book-timing: ease-out;
|
|
6
6
|
--stuic-book-page-bg: transparent; /*var(--stuic-color-surface, #fff);*/
|
|
7
7
|
--stuic-book-page-shadow: none; /*0 2px 16px rgba(0, 0, 0, 0.15);*/
|
|
8
|
-
--stuic-book-radius: var(--radius-sm, 2px);
|
|
9
8
|
--stuic-book-page-width: 300px;
|
|
10
9
|
--stuic-book-page-height: 400px;
|
|
11
10
|
}
|
|
@@ -25,7 +24,7 @@
|
|
|
25
24
|
vertical-align: top;
|
|
26
25
|
text-align: initial;
|
|
27
26
|
background: var(--stuic-book-page-bg);
|
|
28
|
-
border-radius: var(--stuic-book-radius);
|
|
27
|
+
border-radius: var(--stuic-book-radius, var(--stuic-radius));
|
|
29
28
|
box-shadow: var(--stuic-book-page-shadow);
|
|
30
29
|
transition: width var(--stuic-book-duration) var(--stuic-book-timing);
|
|
31
30
|
}
|
|
@@ -65,7 +64,7 @@
|
|
|
65
64
|
backface-visibility: hidden;
|
|
66
65
|
-webkit-backface-visibility: hidden;
|
|
67
66
|
background: var(--stuic-book-page-bg);
|
|
68
|
-
border-radius: 0 var(--stuic-book-radius) var(--stuic-book-radius) 0;
|
|
67
|
+
border-radius: 0 var(--stuic-book-radius, var(--stuic-radius)) var(--stuic-book-radius, var(--stuic-radius)) 0;
|
|
69
68
|
overflow: hidden;
|
|
70
69
|
}
|
|
71
70
|
|
|
@@ -83,7 +82,7 @@
|
|
|
83
82
|
-webkit-backface-visibility: hidden;
|
|
84
83
|
transform: rotateY(180deg);
|
|
85
84
|
background: var(--stuic-book-page-bg);
|
|
86
|
-
border-radius: var(--stuic-book-radius) 0 0 var(--stuic-book-radius);
|
|
85
|
+
border-radius: var(--stuic-book-radius, var(--stuic-radius)) 0 0 var(--stuic-book-radius, var(--stuic-radius));
|
|
87
86
|
overflow: hidden;
|
|
88
87
|
}
|
|
89
88
|
|
|
@@ -7,10 +7,8 @@
|
|
|
7
7
|
/* prettier-ignore */
|
|
8
8
|
:root {
|
|
9
9
|
/* Component-level customization tokens */
|
|
10
|
-
--stuic-button-radius: var(--radius-md);
|
|
11
10
|
--stuic-button-font-family: var(--font-sans);
|
|
12
11
|
--stuic-button-font-weight: var(--font-weight-medium);
|
|
13
|
-
--stuic-button-transition: 150ms;
|
|
14
12
|
|
|
15
13
|
/* Focus ring */
|
|
16
14
|
--stuic-button-ring-width: 3px;
|
|
@@ -69,7 +67,7 @@
|
|
|
69
67
|
/* Box model */
|
|
70
68
|
border-width: 1px;
|
|
71
69
|
border-style: solid;
|
|
72
|
-
border-radius: var(--stuic-button-radius);
|
|
70
|
+
border-radius: var(--stuic-button-radius, var(--stuic-radius));
|
|
73
71
|
|
|
74
72
|
/* Interaction */
|
|
75
73
|
cursor: pointer;
|
|
@@ -77,10 +75,10 @@
|
|
|
77
75
|
-webkit-tap-highlight-color: transparent; /* Remove iOS tap highlight */
|
|
78
76
|
touch-action: manipulation; /* Disable double-tap zoom for faster response */
|
|
79
77
|
transition:
|
|
80
|
-
background var(--stuic-button-transition),
|
|
81
|
-
color var(--stuic-button-transition),
|
|
82
|
-
border-color var(--stuic-button-transition),
|
|
83
|
-
opacity var(--stuic-button-transition);
|
|
78
|
+
background var(--stuic-button-transition, var(--stuic-transition)),
|
|
79
|
+
color var(--stuic-button-transition, var(--stuic-transition)),
|
|
80
|
+
border-color var(--stuic-button-transition, var(--stuic-transition)),
|
|
81
|
+
opacity var(--stuic-button-transition, var(--stuic-transition));
|
|
84
82
|
|
|
85
83
|
/* Colors - use internal vars set by intent/variant */
|
|
86
84
|
background: var(--_bg);
|
|
@@ -355,12 +353,12 @@
|
|
|
355
353
|
box-shadow: var(--stuic-button-raised-offset) var(--stuic-button-raised-offset) 0 0
|
|
356
354
|
var(--stuic-button-raised-color);
|
|
357
355
|
transition:
|
|
358
|
-
background var(--stuic-button-transition),
|
|
359
|
-
color var(--stuic-button-transition),
|
|
360
|
-
border-color var(--stuic-button-transition),
|
|
361
|
-
opacity var(--stuic-button-transition),
|
|
362
|
-
box-shadow var(--stuic-button-transition),
|
|
363
|
-
transform var(--stuic-button-transition);
|
|
356
|
+
background var(--stuic-button-transition, var(--stuic-transition)),
|
|
357
|
+
color var(--stuic-button-transition, var(--stuic-transition)),
|
|
358
|
+
border-color var(--stuic-button-transition, var(--stuic-transition)),
|
|
359
|
+
opacity var(--stuic-button-transition, var(--stuic-transition)),
|
|
360
|
+
box-shadow var(--stuic-button-transition, var(--stuic-transition)),
|
|
361
|
+
transform var(--stuic-button-transition, var(--stuic-transition));
|
|
364
362
|
}
|
|
365
363
|
|
|
366
364
|
.stuic-button[data-raised]:active:not(:disabled) {
|
|
@@ -6,11 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
:root {
|
|
8
8
|
/* Structure - reference Tailwind vars where applicable */
|
|
9
|
-
--stuic-button-group-radius: var(--radius-md);
|
|
10
9
|
--stuic-button-group-padding: 0.1rem;
|
|
11
10
|
--stuic-button-group-gap: 0.25rem;
|
|
12
|
-
--stuic-button-group-border-width: 1px;
|
|
13
|
-
--stuic-button-group-transition: 150ms;
|
|
14
11
|
|
|
15
12
|
/* Button sizing - 44px is Apple HIG minimum touch target */
|
|
16
13
|
--stuic-button-group-button-padding-x: 0.75rem;
|
|
@@ -56,9 +53,9 @@
|
|
|
56
53
|
|
|
57
54
|
/* Box model */
|
|
58
55
|
padding: var(--stuic-button-group-padding);
|
|
59
|
-
border-width: var(--stuic-button-group-border-width);
|
|
56
|
+
border-width: var(--stuic-button-group-border-width, var(--stuic-border-width));
|
|
60
57
|
border-style: solid;
|
|
61
|
-
border-radius: var(--stuic-button-group-radius);
|
|
58
|
+
border-radius: var(--stuic-button-group-radius, var(--stuic-radius));
|
|
62
59
|
|
|
63
60
|
/* Colors */
|
|
64
61
|
background: var(--stuic-button-group-bg);
|
|
@@ -109,7 +106,7 @@
|
|
|
109
106
|
var(--stuic-button-group-button-padding-x);
|
|
110
107
|
min-height: var(--stuic-button-group-button-min-height);
|
|
111
108
|
border: none;
|
|
112
|
-
border-radius: var(--stuic-button-group-radius);
|
|
109
|
+
border-radius: var(--stuic-button-group-radius, var(--stuic-radius));
|
|
113
110
|
|
|
114
111
|
/* Typography */
|
|
115
112
|
white-space: nowrap;
|
|
@@ -128,8 +125,8 @@
|
|
|
128
125
|
|
|
129
126
|
/* Transition */
|
|
130
127
|
transition:
|
|
131
|
-
background var(--stuic-button-group-transition),
|
|
132
|
-
color var(--stuic-button-group-transition);
|
|
128
|
+
background var(--stuic-button-group-transition, var(--stuic-transition)),
|
|
129
|
+
color var(--stuic-button-group-transition, var(--stuic-transition));
|
|
133
130
|
|
|
134
131
|
/* Focus */
|
|
135
132
|
outline: none;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { HTMLAttributes, HTMLAnchorAttributes } from "svelte/elements";
|
|
3
|
+
import type { Snippet } from "svelte";
|
|
4
|
+
import type { THC } from "../Thc/Thc.svelte";
|
|
5
|
+
|
|
6
|
+
export type CardVariant = "vertical" | "horizontal";
|
|
7
|
+
|
|
8
|
+
export interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "children" | "title"> {
|
|
9
|
+
/** Image URL for the top (vertical) or side (horizontal) image area */
|
|
10
|
+
image?: string;
|
|
11
|
+
/** Alt text for the image */
|
|
12
|
+
imageAlt?: string;
|
|
13
|
+
/** Small label above the title (category, date, tag) */
|
|
14
|
+
eyebrow?: THC;
|
|
15
|
+
/** Card title */
|
|
16
|
+
title?: THC;
|
|
17
|
+
/** Short description below the title */
|
|
18
|
+
description?: THC;
|
|
19
|
+
/** Layout variant */
|
|
20
|
+
variant?: CardVariant;
|
|
21
|
+
/** When provided, the card renders as <a> */
|
|
22
|
+
href?: string;
|
|
23
|
+
/** Disabled state */
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
/** Override the entire card body */
|
|
26
|
+
children?: Snippet;
|
|
27
|
+
/** Override the image area */
|
|
28
|
+
renderImage?: Snippet<[{ image: string; imageAlt: string }]>;
|
|
29
|
+
/** Badge/overlay positioned over the image */
|
|
30
|
+
renderBadge?: Snippet;
|
|
31
|
+
/** Override the content area (eyebrow + title + description) */
|
|
32
|
+
renderContent?: Snippet<[{ eyebrow?: THC; title?: THC; description?: THC }]>;
|
|
33
|
+
/** Footer area (action buttons, metadata, etc.) */
|
|
34
|
+
renderFooter?: Snippet;
|
|
35
|
+
/** Skip all default styling */
|
|
36
|
+
unstyled?: boolean;
|
|
37
|
+
/** Additional CSS classes */
|
|
38
|
+
class?: string;
|
|
39
|
+
/** Class for the image container */
|
|
40
|
+
classImage?: string;
|
|
41
|
+
/** Class for the content area */
|
|
42
|
+
classContent?: string;
|
|
43
|
+
/** Class for the footer area */
|
|
44
|
+
classFooter?: string;
|
|
45
|
+
/** Bindable element reference */
|
|
46
|
+
el?: HTMLElement;
|
|
47
|
+
}
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<script lang="ts">
|
|
51
|
+
import { twMerge } from "../../utils/tw-merge.js";
|
|
52
|
+
import Thc from "../Thc/Thc.svelte";
|
|
53
|
+
|
|
54
|
+
let {
|
|
55
|
+
image,
|
|
56
|
+
imageAlt,
|
|
57
|
+
eyebrow,
|
|
58
|
+
title,
|
|
59
|
+
description,
|
|
60
|
+
variant = "vertical",
|
|
61
|
+
href,
|
|
62
|
+
disabled = false,
|
|
63
|
+
children,
|
|
64
|
+
renderImage,
|
|
65
|
+
renderBadge,
|
|
66
|
+
renderContent,
|
|
67
|
+
renderFooter,
|
|
68
|
+
unstyled = false,
|
|
69
|
+
class: classProp,
|
|
70
|
+
classImage: classImageProp,
|
|
71
|
+
classContent: classContentProp,
|
|
72
|
+
classFooter: classFooterProp,
|
|
73
|
+
el = $bindable(),
|
|
74
|
+
onclick,
|
|
75
|
+
...rest
|
|
76
|
+
}: Props = $props();
|
|
77
|
+
|
|
78
|
+
let _class = $derived(unstyled ? classProp : twMerge("stuic-card", classProp));
|
|
79
|
+
let _classImage = $derived(unstyled ? classImageProp : twMerge("stuic-card-image", classImageProp));
|
|
80
|
+
let _classContent = $derived(unstyled ? classContentProp : twMerge("stuic-card-content", classContentProp));
|
|
81
|
+
let _classFooter = $derived(unstyled ? classFooterProp : twMerge("stuic-card-footer", classFooterProp));
|
|
82
|
+
|
|
83
|
+
let _isInteractive = $derived(!!(href || onclick));
|
|
84
|
+
let _hasImage = $derived(!!(image || renderImage));
|
|
85
|
+
let _hasContent = $derived(!!(eyebrow || title || description || renderContent));
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
{#snippet cardInner()}
|
|
89
|
+
{#if children}
|
|
90
|
+
{@render children()}
|
|
91
|
+
{:else}
|
|
92
|
+
{#if _hasImage}
|
|
93
|
+
<div class={_classImage}>
|
|
94
|
+
{#if renderImage}
|
|
95
|
+
{@render renderImage({ image: image ?? "", imageAlt: imageAlt ?? "" })}
|
|
96
|
+
{:else if image}
|
|
97
|
+
<img src={image} alt={imageAlt ?? ""} />
|
|
98
|
+
{/if}
|
|
99
|
+
{#if renderBadge}
|
|
100
|
+
<div class={unstyled ? undefined : "stuic-card-badge"}>
|
|
101
|
+
{@render renderBadge()}
|
|
102
|
+
</div>
|
|
103
|
+
{/if}
|
|
104
|
+
</div>
|
|
105
|
+
{/if}
|
|
106
|
+
{#if renderContent}
|
|
107
|
+
<div class={_classContent}>
|
|
108
|
+
{@render renderContent({ eyebrow, title, description })}
|
|
109
|
+
</div>
|
|
110
|
+
{:else if _hasContent}
|
|
111
|
+
<div class={_classContent}>
|
|
112
|
+
{#if eyebrow}
|
|
113
|
+
<div class={unstyled ? undefined : "stuic-card-eyebrow"}><Thc thc={eyebrow} /></div>
|
|
114
|
+
{/if}
|
|
115
|
+
{#if title}
|
|
116
|
+
<div class={unstyled ? undefined : "stuic-card-title"}><Thc thc={title} /></div>
|
|
117
|
+
{/if}
|
|
118
|
+
{#if description}
|
|
119
|
+
<div class={unstyled ? undefined : "stuic-card-description"}><Thc thc={description} /></div>
|
|
120
|
+
{/if}
|
|
121
|
+
</div>
|
|
122
|
+
{/if}
|
|
123
|
+
{#if renderFooter}
|
|
124
|
+
<div class={_classFooter}>
|
|
125
|
+
{@render renderFooter()}
|
|
126
|
+
</div>
|
|
127
|
+
{/if}
|
|
128
|
+
{/if}
|
|
129
|
+
{/snippet}
|
|
130
|
+
|
|
131
|
+
{#if href}
|
|
132
|
+
<a
|
|
133
|
+
{href}
|
|
134
|
+
bind:this={el}
|
|
135
|
+
class={_class}
|
|
136
|
+
data-variant={!unstyled ? variant : undefined}
|
|
137
|
+
data-interactive={!unstyled ? "" : undefined}
|
|
138
|
+
data-disabled={!unstyled && disabled ? "" : undefined}
|
|
139
|
+
aria-disabled={disabled ? "true" : undefined}
|
|
140
|
+
{...rest as HTMLAnchorAttributes}
|
|
141
|
+
>
|
|
142
|
+
{@render cardInner()}
|
|
143
|
+
</a>
|
|
144
|
+
{:else if onclick}
|
|
145
|
+
<button
|
|
146
|
+
type="button"
|
|
147
|
+
bind:this={el}
|
|
148
|
+
class={_class}
|
|
149
|
+
data-variant={!unstyled ? variant : undefined}
|
|
150
|
+
data-interactive={!unstyled ? "" : undefined}
|
|
151
|
+
data-disabled={!unstyled && disabled ? "" : undefined}
|
|
152
|
+
{disabled}
|
|
153
|
+
{onclick}
|
|
154
|
+
{...rest as any}
|
|
155
|
+
>
|
|
156
|
+
{@render cardInner()}
|
|
157
|
+
</button>
|
|
158
|
+
{:else}
|
|
159
|
+
<div
|
|
160
|
+
bind:this={el}
|
|
161
|
+
class={_class}
|
|
162
|
+
data-variant={!unstyled ? variant : undefined}
|
|
163
|
+
data-disabled={!unstyled && disabled ? "" : undefined}
|
|
164
|
+
{...rest}
|
|
165
|
+
>
|
|
166
|
+
{@render cardInner()}
|
|
167
|
+
</div>
|
|
168
|
+
{/if}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { THC } from "../Thc/Thc.svelte";
|
|
4
|
+
export type CardVariant = "vertical" | "horizontal";
|
|
5
|
+
export interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "children" | "title"> {
|
|
6
|
+
/** Image URL for the top (vertical) or side (horizontal) image area */
|
|
7
|
+
image?: string;
|
|
8
|
+
/** Alt text for the image */
|
|
9
|
+
imageAlt?: string;
|
|
10
|
+
/** Small label above the title (category, date, tag) */
|
|
11
|
+
eyebrow?: THC;
|
|
12
|
+
/** Card title */
|
|
13
|
+
title?: THC;
|
|
14
|
+
/** Short description below the title */
|
|
15
|
+
description?: THC;
|
|
16
|
+
/** Layout variant */
|
|
17
|
+
variant?: CardVariant;
|
|
18
|
+
/** When provided, the card renders as <a> */
|
|
19
|
+
href?: string;
|
|
20
|
+
/** Disabled state */
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
/** Override the entire card body */
|
|
23
|
+
children?: Snippet;
|
|
24
|
+
/** Override the image area */
|
|
25
|
+
renderImage?: Snippet<[{
|
|
26
|
+
image: string;
|
|
27
|
+
imageAlt: string;
|
|
28
|
+
}]>;
|
|
29
|
+
/** Badge/overlay positioned over the image */
|
|
30
|
+
renderBadge?: Snippet;
|
|
31
|
+
/** Override the content area (eyebrow + title + description) */
|
|
32
|
+
renderContent?: Snippet<[{
|
|
33
|
+
eyebrow?: THC;
|
|
34
|
+
title?: THC;
|
|
35
|
+
description?: THC;
|
|
36
|
+
}]>;
|
|
37
|
+
/** Footer area (action buttons, metadata, etc.) */
|
|
38
|
+
renderFooter?: Snippet;
|
|
39
|
+
/** Skip all default styling */
|
|
40
|
+
unstyled?: boolean;
|
|
41
|
+
/** Additional CSS classes */
|
|
42
|
+
class?: string;
|
|
43
|
+
/** Class for the image container */
|
|
44
|
+
classImage?: string;
|
|
45
|
+
/** Class for the content area */
|
|
46
|
+
classContent?: string;
|
|
47
|
+
/** Class for the footer area */
|
|
48
|
+
classFooter?: string;
|
|
49
|
+
/** Bindable element reference */
|
|
50
|
+
el?: HTMLElement;
|
|
51
|
+
}
|
|
52
|
+
declare const Card: import("svelte").Component<Props, {}, "el">;
|
|
53
|
+
type Card = ReturnType<typeof Card>;
|
|
54
|
+
export default Card;
|