@stisla/style 3.0.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +16 -0
  3. package/dist/accordion/accordion.css +194 -0
  4. package/dist/alert/alert.css +138 -0
  5. package/dist/autocomplete/autocomplete.css +193 -0
  6. package/dist/avatar/avatar.css +142 -0
  7. package/dist/avatar-group/avatar-group.css +42 -0
  8. package/dist/badge/badge.css +74 -0
  9. package/dist/breadcrumb/breadcrumb.css +71 -0
  10. package/dist/button/button.css +318 -0
  11. package/dist/button/index.d.ts +1 -0
  12. package/dist/button/index.js +6 -0
  13. package/dist/button-group/button-group.css +108 -0
  14. package/dist/card/card.css +219 -0
  15. package/dist/carousel/carousel.css +170 -0
  16. package/dist/checkbox/checkbox.css +98 -0
  17. package/dist/chunk-K45KLI3Y.js +74 -0
  18. package/dist/collapsible/collapsible.css +36 -0
  19. package/dist/combobox/combobox.css +106 -0
  20. package/dist/combobox/combobox.tomselect.css +251 -0
  21. package/dist/config-CARtrJ7I.d.ts +61 -0
  22. package/dist/dialog/dialog.css +258 -0
  23. package/dist/drawer/drawer.css +318 -0
  24. package/dist/empty-state/empty-state.css +138 -0
  25. package/dist/field/field.css +70 -0
  26. package/dist/icon-box/icon-box.css +64 -0
  27. package/dist/illustration/illustration.css +103 -0
  28. package/dist/index.d.ts +14 -0
  29. package/dist/index.js +60 -0
  30. package/dist/indicator/indicator.css +84 -0
  31. package/dist/input/input.css +220 -0
  32. package/dist/input-group/input-group.css +141 -0
  33. package/dist/kbd/kbd.css +55 -0
  34. package/dist/link/link.css +28 -0
  35. package/dist/list-group/list-group.css +261 -0
  36. package/dist/media/media.css +115 -0
  37. package/dist/menu/menu.css +237 -0
  38. package/dist/meter/meter.css +124 -0
  39. package/dist/navbar/navbar.css +170 -0
  40. package/dist/page/page.css +95 -0
  41. package/dist/pagination/pagination.css +125 -0
  42. package/dist/placeholders/placeholders.css +58 -0
  43. package/dist/popover/popover.css +251 -0
  44. package/dist/progress/progress.css +139 -0
  45. package/dist/radio/radio.css +81 -0
  46. package/dist/scroll-area/scroll-area.css +25 -0
  47. package/dist/scroll-area/scroll-area.overlayscrollbars.css +42 -0
  48. package/dist/select/select.css +282 -0
  49. package/dist/separator/separator.css +26 -0
  50. package/dist/sidebar/sidebar.css +493 -0
  51. package/dist/slider/slider.css +159 -0
  52. package/dist/spinner/spinner.css +65 -0
  53. package/dist/switch/switch.css +91 -0
  54. package/dist/table/table.css +284 -0
  55. package/dist/tabs/tabs.css +137 -0
  56. package/dist/textarea/textarea.css +99 -0
  57. package/dist/timeline/timeline.css +271 -0
  58. package/dist/toast/toast.css +267 -0
  59. package/dist/toggle/toggle.css +125 -0
  60. package/dist/toggle-group/toggle-group.css +87 -0
  61. package/dist/tooltip/tooltip.css +95 -0
  62. package/package.json +46 -0
  63. package/src/theme.css +151 -0
@@ -0,0 +1,87 @@
1
+ /* @stisla/style — Toggle group. Ported from src/scss/components/_toggle-group.scss. A pill container
2
+ * hosting a row (or column) of .toggle children. The container owns the frame (rim + radius + bg);
3
+ * members go ghost-rest (no individual rims) so the cluster reads as one segmented control. Members
4
+ * get a concentric inner radius (outer − padding). References the @theme tokens (colors var(--color-*),
5
+ * spacing/sizes --spacing(n), radius var(--radius-*)); only no-namespace customs use --st-*
6
+ * (border-width). Knobs are --toggle-group-*; sizes compact/roomy → sm/lg. @layer components.
7
+ * Authoring rules: ../../../../PORTING.md */
8
+
9
+ @layer components {
10
+ /* === Shared base === container chrome + member overrides (horizontal + vertical). */
11
+ .toggle-group,
12
+ .toggle-group--vertical {
13
+ position: relative;
14
+ display: inline-flex;
15
+ align-items: stretch;
16
+ vertical-align: middle;
17
+ padding: var(--toggle-group-padding-block, --spacing(0.5))
18
+ var(--toggle-group-padding-inline, --spacing(0.5));
19
+ gap: var(--toggle-group-gap, --spacing(0.5));
20
+ background: var(--toggle-group-bg, transparent);
21
+ border: var(--toggle-group-border-width, var(--st-border-width)) solid
22
+ var(--toggle-group-border-color, var(--color-border));
23
+ border-radius: var(--toggle-group-radius, var(--radius-md));
24
+
25
+ /* Member toggles — concentric inner radius + ghost rest (the parent rim owns the frame). */
26
+ > .toggle {
27
+ --toggle-radius: calc(
28
+ var(--toggle-group-radius, var(--radius-md)) -
29
+ var(--toggle-group-padding-inline, --spacing(0.5))
30
+ );
31
+ --toggle-bg: transparent;
32
+ --toggle-border-color: transparent;
33
+ }
34
+ }
35
+
36
+ /* === Horizontal === outer height locked; children fill via flex stretch + height: 100% (box model
37
+ handles the inner-area math). Scoped via :not(--vertical) so it doesn't leak into vertical mode. */
38
+ .toggle-group:not(.toggle-group--vertical) {
39
+ height: var(--toggle-group-height, --spacing(9));
40
+
41
+ /* Overflow → scroll, not squish: cap at the container and scroll horizontally (hidden scrollbar;
42
+ the half-clipped trailing segment is the "more this way" cue). */
43
+ max-width: 100%;
44
+ overflow-x: auto;
45
+ scrollbar-width: none;
46
+ &::-webkit-scrollbar {
47
+ display: none;
48
+ }
49
+
50
+ > .toggle {
51
+ height: 100%;
52
+ flex-shrink: 0;
53
+ }
54
+
55
+ /* Icon-only inside the group: width follows the stretched cross-axis so the chip stays square. */
56
+ > .toggle--icon-only {
57
+ width: auto;
58
+ aspect-ratio: 1;
59
+ }
60
+ }
61
+
62
+ /* === Vertical === stacked column reading as a menu list; block-level so it fills its parent width.
63
+ Members keep a compact menu-list height, full-width, start-aligned. */
64
+ .toggle-group--vertical {
65
+ display: flex;
66
+ flex-direction: column;
67
+ width: 100%;
68
+ height: auto;
69
+
70
+ > .toggle {
71
+ --toggle-height: --spacing(8);
72
+ width: 100%;
73
+ justify-content: flex-start;
74
+ text-align: start;
75
+ }
76
+ }
77
+
78
+ /* === Sizes (base = md) === outer container scales; padding + gap stay so the inner area tracks it. */
79
+ .toggle-group--sm {
80
+ --toggle-group-radius: var(--radius-sm);
81
+ --toggle-group-height: --spacing(7);
82
+ }
83
+ .toggle-group--lg {
84
+ --toggle-group-radius: var(--radius-lg);
85
+ --toggle-group-height: --spacing(11);
86
+ }
87
+ }
@@ -0,0 +1,95 @@
1
+ /* @stisla/style — Tooltip. Ported from src/scss/components/_tooltip.scss. An inverse-surface chip
2
+ * (bg = foreground, text = background) positioned by the JS layer (Floating UI), shown via
3
+ * [data-state="open"] + [data-placement]. References the @theme tokens: colors var(--color-*),
4
+ * sizes/spacing --spacing(n), type var(--text-*) / var(--leading-*), radius var(--radius-*),
5
+ * shadow var(--shadow-*). Only no-namespace customs use --st-* (duration, z-index); z-index routes
6
+ * through the z-index scale (--z-index-tooltip, the top tier). Knobs are --tooltip-*. State via
7
+ * data-* attributes, never is-*. Positioning behavior ships with the JS layer. @layer components.
8
+ * Authoring rules: ../../../../PORTING.md */
9
+
10
+ @layer components {
11
+ .tooltip {
12
+ position: fixed;
13
+ top: 0;
14
+ left: 0;
15
+ z-index: var(--tooltip-z-index, var(--z-index-tooltip));
16
+ display: none;
17
+ max-width: var(--tooltip-max-width, --spacing(60));
18
+ margin: 0;
19
+ pointer-events: none;
20
+ opacity: 0;
21
+ /* Resting transform = "above the trigger, easing up from below"; the per-side rules below flip
22
+ the direction so the entrance always reads as moving away from the anchored edge. */
23
+ transform: translateY(--spacing(1));
24
+ transition:
25
+ opacity var(--tooltip-transition-duration, var(--transition-duration-fast)) ease,
26
+ transform var(--tooltip-transition-duration, var(--transition-duration-fast)) ease;
27
+ }
28
+
29
+ .tooltip[data-state="open"] {
30
+ display: block;
31
+ opacity: 1;
32
+ transform: none;
33
+ }
34
+
35
+ /* Per-placement resting transform — Floating UI's resolved placement (which may differ from the
36
+ requested side after flip()) sets [data-placement], so the entrance tracks the anchored edge. */
37
+ .tooltip[data-placement^="bottom"] {
38
+ transform: translateY(calc(--spacing(1) * -1));
39
+ }
40
+ .tooltip[data-placement^="left"] {
41
+ transform: translateX(--spacing(1));
42
+ }
43
+ .tooltip[data-placement^="right"] {
44
+ transform: translateX(calc(--spacing(1) * -1));
45
+ }
46
+ .tooltip[data-placement^="bottom"][data-state="open"],
47
+ .tooltip[data-placement^="left"][data-state="open"],
48
+ .tooltip[data-placement^="right"][data-state="open"] {
49
+ transform: none;
50
+ }
51
+
52
+ /* === Inner === the visible chip; holds the bg / padding / radius so the arrow can overlap its
53
+ edge cleanly while .tooltip itself stays a positioning shell. */
54
+ .tooltip__inner {
55
+ padding: var(--tooltip-padding-block, --spacing(1.5))
56
+ var(--tooltip-padding-inline, --spacing(2.5));
57
+ font-size: var(--tooltip-font-size, var(--text-xs));
58
+ line-height: var(--tooltip-line-height, var(--leading-snug));
59
+ color: var(--tooltip-color, var(--color-background));
60
+ text-align: center;
61
+ background-color: var(--tooltip-bg, var(--color-foreground));
62
+ border-radius: var(--tooltip-radius, var(--radius-sm));
63
+ box-shadow: var(--tooltip-shadow, var(--shadow-sm));
64
+ word-wrap: break-word;
65
+ }
66
+
67
+ /* === Arrow === a small square rotated 45°; JS sets the along-axis offset, these rules pin the
68
+ cross-axis so half the diamond sits inside the chip and half sticks out as the point. */
69
+ .tooltip__arrow {
70
+ position: absolute;
71
+ width: var(--tooltip-arrow-size, --spacing(2));
72
+ height: var(--tooltip-arrow-size, --spacing(2));
73
+ background-color: var(--tooltip-bg, var(--color-foreground));
74
+ transform: rotate(45deg);
75
+ }
76
+
77
+ .tooltip[data-placement^="top"] .tooltip__arrow {
78
+ bottom: calc(var(--tooltip-arrow-size, --spacing(2)) * -0.5);
79
+ }
80
+ .tooltip[data-placement^="bottom"] .tooltip__arrow {
81
+ top: calc(var(--tooltip-arrow-size, --spacing(2)) * -0.5);
82
+ }
83
+ .tooltip[data-placement^="left"] .tooltip__arrow {
84
+ right: calc(var(--tooltip-arrow-size, --spacing(2)) * -0.5);
85
+ }
86
+ .tooltip[data-placement^="right"] .tooltip__arrow {
87
+ left: calc(var(--tooltip-arrow-size, --spacing(2)) * -0.5);
88
+ }
89
+
90
+ @media (prefers-reduced-motion: reduce) {
91
+ .tooltip {
92
+ transition: none;
93
+ }
94
+ }
95
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@stisla/style",
3
+ "version": "3.0.0-beta.8",
4
+ "description": "Stisla framework-agnostic style layer — the Tailwind @theme foundation (theme.css) + pure-JS composer + per-component configs + compiled component CSS. Zero framework deps.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ },
12
+ "./button": {
13
+ "types": "./dist/button/index.d.ts",
14
+ "import": "./dist/button/index.js"
15
+ },
16
+ "./button.css": "./dist/button/button.css",
17
+ "./theme.css": "./src/theme.css",
18
+ "./package.json": "./package.json"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "src/theme.css",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "sideEffects": [
27
+ "**/*.css"
28
+ ],
29
+ "devDependencies": {
30
+ "tailwindcss": "^4.0.0",
31
+ "tsup": "^8.0.0",
32
+ "typescript": "^5.4.0"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/stisla/stisla.git",
37
+ "directory": "next/packages/style"
38
+ },
39
+ "homepage": "https://github.com/stisla/stisla#readme",
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "scripts": {
44
+ "build": "tsup && node scripts/copy-css.mjs"
45
+ }
46
+ }
package/src/theme.css ADDED
@@ -0,0 +1,151 @@
1
+ /* @stisla/style — THE theme/foundation layer. Tailwind v4 @theme: one definition emits the CSS
2
+ * variables (referenced in our component CSS) AND generates the utilities. There is no parallel
3
+ * token system — components read these theme vars directly:
4
+ * colors → var(--color-*) type → var(--text-*) / var(--leading-*) / var(--font-weight-*)
5
+ * radius → var(--radius-*) shadow → var(--shadow-*) spacing → --spacing(n)
6
+ * tint → --alpha(var(--color-x) / N%)
7
+ * z-index + duration ride Tailwind's namespaces (--z-index-*, --transition-duration-*) in a
8
+ * @theme static block: that generates z-* / duration-* utilities AND force-emits the vars so our
9
+ * raw var() refs resolve. Only border-width has no namespace slot, so it stays --st-*.
10
+ * Dark mode overrides --color-* in a scope.
11
+ *
12
+ * This file is a PURE @theme — it does NOT import Tailwind. Tailwind is pulled in once by the
13
+ * consumer (or by the @stisla/css build), then this file is imported after it:
14
+ * @import "tailwindcss";
15
+ * @import "@stisla/style/theme.css"; */
16
+
17
+ @theme {
18
+ /* Drop Tailwind's default palette; ship only semantic colors. */
19
+ --color-*: initial;
20
+
21
+ /* Intent (5 pairs) */
22
+ --color-primary: oklch(0.639 0.1844 257.69);
23
+ --color-primary-foreground: oklch(1 0 0);
24
+ --color-success: oklch(0.6966 0.1853 149.54);
25
+ --color-success-foreground: oklch(1 0 0);
26
+ --color-warning: oklch(0.7697 0.1645 70.61);
27
+ --color-warning-foreground: oklch(0.27 0 0);
28
+ --color-danger: oklch(0.6155 0.2229 26.82);
29
+ --color-danger-foreground: oklch(1 0 0);
30
+ --color-info: oklch(0.677589 0.148143 238.1044);
31
+ --color-info-foreground: oklch(1 0 0);
32
+
33
+ /* Surface (8) */
34
+ --color-background: oklch(1 0 0);
35
+ --color-foreground: oklch(0.27 0 0);
36
+ --color-surface: oklch(1 0 0);
37
+ --color-surface-2: oklch(0.98 0 0);
38
+ --color-surface-3: oklch(0.97 0 0);
39
+ --color-border: oklch(0.95 0 0);
40
+ --color-border-strong: oklch(0.93 0 0);
41
+ --color-muted-foreground: oklch(0.52 0 0);
42
+
43
+ /* Overlay (theme-independent chrome) */
44
+ --color-overlay: oklch(0.155 0 0);
45
+ --color-overlay-foreground: oklch(0.98 0 0);
46
+
47
+ /* Interactional */
48
+ --color-neutral: oklch(0.91 0 0);
49
+ --color-neutral-foreground: oklch(0.27 0 0); /* = foreground (light) */
50
+ --color-accent: oklch(0.96 0 0);
51
+ --color-accent-foreground: oklch(0.27 0 0);
52
+ --color-highlight: color-mix(in oklch, var(--color-primary) 12%, transparent);
53
+ --color-highlight-foreground: var(--color-primary);
54
+
55
+ /* Focus */
56
+ --color-ring: var(--color-primary);
57
+
58
+ /* Geometry — our tuned radius + shadow (override Tailwind's defaults; spacing/type stay) */
59
+ --radius-sm: 0.65rem;
60
+ --radius-md: 0.75rem;
61
+ --radius-lg: 1rem;
62
+ --shadow-sm:
63
+ 0 1px 2px 0 color-mix(in oklch, black 5%, transparent),
64
+ 0 1px 3px 0 color-mix(in oklch, black 4%, transparent);
65
+ --shadow-md:
66
+ 0 2px 6px -1px color-mix(in oklch, black 5%, transparent),
67
+ 0 8px 16px -4px color-mix(in oklch, black 6%, transparent);
68
+ --shadow-lg:
69
+ 0 4px 12px -2px color-mix(in oklch, black 6%, transparent),
70
+ 0 16px 36px -8px color-mix(in oklch, black 9%, transparent);
71
+ --shadow-xl:
72
+ 0 8px 24px -4px color-mix(in oklch, black 7%, transparent),
73
+ 0 24px 56px -12px color-mix(in oklch, black 12%, transparent);
74
+
75
+ /* Type families */
76
+ --font-sans:
77
+ "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
78
+ "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji",
79
+ "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
80
+ --font-mono:
81
+ "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
82
+ "Liberation Mono", monospace;
83
+
84
+ /* Line-height scale — re-declared with Tailwind's default values (not changed). Tailwind v4 only
85
+ emits a theme var to :root when a UTILITY uses it; our components reference var(--leading-*) in
86
+ raw component CSS, and no leading-* utility is used anywhere, so without this they'd be
87
+ tree-shaken away and every `line-height: var(--leading-*)` would fall back to the inherited 1.5.
88
+ Declaring them here forces emission so the component line-heights actually apply. */
89
+ --leading-none: 1;
90
+ --leading-tight: 1.25;
91
+ --leading-snug: 1.375;
92
+ --leading-normal: 1.5;
93
+ }
94
+
95
+ @variant dark {
96
+ --color-background: oklch(0.155 0 0);
97
+ --color-foreground: oklch(0.97 0 0);
98
+ --color-surface: oklch(0.18 0 0);
99
+ --color-surface-2: oklch(0.21 0 0);
100
+ --color-surface-3: oklch(0.23 0 0);
101
+ --color-border: oklch(0.25 0 0);
102
+ --color-border-strong: oklch(0.32 0 0);
103
+ --color-muted-foreground: oklch(0.72 0 0);
104
+ --color-neutral: oklch(0.27 0 0);
105
+ --color-neutral-foreground: oklch(0.97 0 0);
106
+ --color-accent: oklch(0.26 0 0);
107
+ --color-accent-foreground: oklch(0.97 0 0);
108
+ }
109
+
110
+ /* z-index + duration scales — Tailwind owns these namespaces, so naming them --z-index-* /
111
+ * --transition-duration-* generates utilities (z-modal, duration-fast, …). `static` forces
112
+ * unconditional emission: our component CSS references them via raw var(), which Tailwind can't
113
+ * see, so without `static` a zero-utility-usage var would be tree-shaken (the --leading-* trap). */
114
+ @theme static {
115
+ --z-index-base: 0;
116
+ --z-index-dropdown: 1000;
117
+ --z-index-sticky: 1020;
118
+ --z-index-overlay: 1030;
119
+ --z-index-modal: 1040;
120
+ --z-index-popover: 1050;
121
+ --z-index-toast: 1060;
122
+ --z-index-tooltip: 1070;
123
+
124
+ --transition-duration-fast: 120ms;
125
+ --transition-duration-normal: 200ms;
126
+ --transition-duration-slow: 320ms;
127
+ }
128
+
129
+ /* Single global default border thickness — NOT a scale, so no Tailwind namespace fits
130
+ * (--border-width-* needs named steps; a bare --border-width generates nothing). Stays --st-*. */
131
+ :root {
132
+ --st-border-width: 1px;
133
+ }
134
+
135
+ /* Base — default body copy is 14px (Stisla's long-standing default), set on <body> so the
136
+ * root stays at the browser default and 1rem = 16px: the spacing scale and every rem-based
137
+ * token remain anchored to 16px. Components set their own font-size (var(--text-sm) etc.);
138
+ * this governs only bare/inherited text and demo content. (Reboot concern — may move to a
139
+ * dedicated reboot layer later; theme.css is the one file every consumer imports, so it lives
140
+ * here for now.) */
141
+ @layer base {
142
+ body {
143
+ font-size: var(--text-sm);
144
+ font-family: var(--font-sans);
145
+ background: var(--color-background);
146
+ color: var(--color-foreground);
147
+ }
148
+ }
149
+
150
+ /* Class-based dark mode for utilities (both hooks Stisla supports). */
151
+ @custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *, .dark, .dark *));