@greese/ui 0.0.0-stage → 1.1.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.
Files changed (288) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +55 -2
  3. package/bin/greese-utilities.mjs +56 -0
  4. package/dist/_layers.scss +2 -0
  5. package/dist/_maps.scss +1884 -0
  6. package/dist/_tokens-base.scss +174 -0
  7. package/dist/_tokens.scss +2140 -0
  8. package/dist/base.css +67 -0
  9. package/dist/colorScheme.d.ts +16 -0
  10. package/dist/colorScheme.js +13 -0
  11. package/dist/contrast.d.ts +15 -0
  12. package/dist/contrast.js +43 -0
  13. package/dist/css/Accordion.css +9 -0
  14. package/dist/css/ActionSelect.css +6 -0
  15. package/dist/css/Alert.css +84 -0
  16. package/dist/css/AppBar.css +35 -0
  17. package/dist/css/AspectRatio.css +40 -0
  18. package/dist/css/AutoLayout.css +508 -0
  19. package/dist/css/Avatar.css +88 -0
  20. package/dist/css/Badge.css +66 -0
  21. package/dist/css/Box.css +640 -0
  22. package/dist/css/Breadcrumbs.css +57 -0
  23. package/dist/css/Button.css +275 -0
  24. package/dist/css/ButtonGroup.css +40 -0
  25. package/dist/css/Card.css +101 -0
  26. package/dist/css/Carousel.css +170 -0
  27. package/dist/css/Center.css +11 -0
  28. package/dist/css/ChatBubble.css +128 -0
  29. package/dist/css/Checkbox.css +65 -0
  30. package/dist/css/Chip.css +124 -0
  31. package/dist/css/ChoiceGroup.css +57 -0
  32. package/dist/css/Code.css +29 -0
  33. package/dist/css/Collapsible.css +126 -0
  34. package/dist/css/ColorPicker.css +191 -0
  35. package/dist/css/Combobox.css +90 -0
  36. package/dist/css/Container.css +30 -0
  37. package/dist/css/Countdown.css +25 -0
  38. package/dist/css/DateField.css +15 -0
  39. package/dist/css/Dialog.css +640 -0
  40. package/dist/css/Diff.css +103 -0
  41. package/dist/css/Divider.css +19 -0
  42. package/dist/css/Dock.css +91 -0
  43. package/dist/css/Field.css +33 -0
  44. package/dist/css/Fieldset.css +54 -0
  45. package/dist/css/FileInput.css +65 -0
  46. package/dist/css/Footer.css +72 -0
  47. package/dist/css/Grid.css +998 -0
  48. package/dist/css/Header.css +89 -0
  49. package/dist/css/Heading.css +6 -0
  50. package/dist/css/Icon.css +12 -0
  51. package/dist/css/IconButton.css +7 -0
  52. package/dist/css/Image.css +69 -0
  53. package/dist/css/Indicator.css +41 -0
  54. package/dist/css/Input.css +115 -0
  55. package/dist/css/Key.css +42 -0
  56. package/dist/css/Link.css +72 -0
  57. package/dist/css/List.css +52 -0
  58. package/dist/css/Media.css +8 -0
  59. package/dist/css/Menu.css +161 -0
  60. package/dist/css/Motion.css +1356 -0
  61. package/dist/css/NumberField.css +49 -0
  62. package/dist/css/OtpField.css +90 -0
  63. package/dist/css/PageTransition.css +991 -0
  64. package/dist/css/Pagination.css +43 -0
  65. package/dist/css/Popover.css +93 -0
  66. package/dist/css/Progress.css +101 -0
  67. package/dist/css/RadialProgress.css +44 -0
  68. package/dist/css/Radio.css +41 -0
  69. package/dist/css/Rating.css +100 -0
  70. package/dist/css/ScrollSpy.css +6 -0
  71. package/dist/css/SegmentedControl.css +101 -0
  72. package/dist/css/Select.css +115 -0
  73. package/dist/css/Sidebar.css +207 -0
  74. package/dist/css/Skeleton.css +48 -0
  75. package/dist/css/Slider.css +75 -0
  76. package/dist/css/Spacer.css +34 -0
  77. package/dist/css/SpeedDial.css +165 -0
  78. package/dist/css/Spinner.css +44 -0
  79. package/dist/css/Stack.css +528 -0
  80. package/dist/css/Stat.css +107 -0
  81. package/dist/css/Status.css +86 -0
  82. package/dist/css/Steps.css +201 -0
  83. package/dist/css/Swap.css +49 -0
  84. package/dist/css/Switch.css +66 -0
  85. package/dist/css/Table.css +269 -0
  86. package/dist/css/Tabs.css +119 -0
  87. package/dist/css/Text.css +60 -0
  88. package/dist/css/TextRotate.css +147 -0
  89. package/dist/css/Textarea.css +107 -0
  90. package/dist/css/ThemeProvider.css +6 -0
  91. package/dist/css/Tile.css +18 -0
  92. package/dist/css/Toast.css +110 -0
  93. package/dist/css/ToggleButton.css +20 -0
  94. package/dist/css/Tooltip.css +94 -0
  95. package/dist/css/Type.css +211 -0
  96. package/dist/css/Visibility.css +78 -0
  97. package/dist/css/VisuallyHidden.css +15 -0
  98. package/dist/css/core.css +251 -0
  99. package/dist/css.d.ts +29 -0
  100. package/dist/css.js +28 -0
  101. package/dist/effect-classes.d.ts +8 -0
  102. package/dist/effect-classes.js +5 -0
  103. package/dist/effects/css.d.ts +71 -0
  104. package/dist/effects/css.js +184 -0
  105. package/dist/effects/definitions.d.ts +555 -0
  106. package/dist/effects/definitions.js +379 -0
  107. package/dist/effects/frames.d.ts +18 -0
  108. package/dist/effects/frames.js +68 -0
  109. package/dist/effects/sequence.d.ts +33 -0
  110. package/dist/effects/sequence.js +106 -0
  111. package/dist/effects.d.ts +30 -0
  112. package/dist/effects.js +30 -0
  113. package/dist/greese.css +11919 -0
  114. package/dist/index.d.ts +10 -0
  115. package/dist/index.js +10 -0
  116. package/dist/kebab.d.ts +2 -0
  117. package/dist/kebab.js +2 -0
  118. package/dist/palette.css +249 -0
  119. package/dist/palette.d.ts +599 -0
  120. package/dist/palette.js +334 -0
  121. package/dist/shapes.d.ts +193 -0
  122. package/dist/shapes.js +852 -0
  123. package/dist/storage.d.ts +47 -0
  124. package/dist/storage.js +118 -0
  125. package/dist/style-manifest.json +3017 -0
  126. package/dist/theme.d.ts +71 -0
  127. package/dist/theme.js +180 -0
  128. package/dist/tokens.css +253 -0
  129. package/dist/tokens.d.ts +343 -0
  130. package/dist/tokens.js +179 -0
  131. package/dist/typography.d.ts +55 -0
  132. package/dist/typography.js +144 -0
  133. package/dist/utilities.css +6975 -0
  134. package/dist/utilities.d.ts +82 -0
  135. package/dist/utilities.js +636 -0
  136. package/dist/utilitiesFiles.d.ts +18 -0
  137. package/dist/utilitiesFiles.js +26 -0
  138. package/dist/vite.d.ts +40 -0
  139. package/dist/vite.js +43 -0
  140. package/package.json +131 -4
  141. package/src/components/Accordion/Accordion.scss +9 -0
  142. package/src/components/ActionSelect/ActionSelect.scss +6 -0
  143. package/src/components/Alert/Alert.scss +71 -0
  144. package/src/components/AppBar/AppBar.scss +43 -0
  145. package/src/components/AspectRatio/AspectRatio.scss +22 -0
  146. package/src/components/AutoLayout/AutoLayout.scss +90 -0
  147. package/src/components/Avatar/Avatar.scss +91 -0
  148. package/src/components/Badge/Badge.scss +52 -0
  149. package/src/components/Box/Box.scss +63 -0
  150. package/src/components/Breadcrumbs/Breadcrumbs.scss +59 -0
  151. package/src/components/Button/Button.scss +231 -0
  152. package/src/components/ButtonGroup/ButtonGroup.scss +56 -0
  153. package/src/components/Card/Card.scss +99 -0
  154. package/src/components/Carousel/Carousel.scss +161 -0
  155. package/src/components/Center/Center.scss +11 -0
  156. package/src/components/ChatBubble/ChatBubble.scss +119 -0
  157. package/src/components/Checkbox/Checkbox.scss +66 -0
  158. package/src/components/Chip/Chip.scss +119 -0
  159. package/src/components/ChoiceGroup/ChoiceGroup.scss +69 -0
  160. package/src/components/Code/Code.scss +28 -0
  161. package/src/components/Collapsible/Collapsible.scss +136 -0
  162. package/src/components/ColorPicker/ColorPicker.scss +235 -0
  163. package/src/components/Combobox/Combobox.scss +83 -0
  164. package/src/components/Container/Container.scss +28 -0
  165. package/src/components/Countdown/Countdown.scss +28 -0
  166. package/src/components/DateField/DateField.scss +19 -0
  167. package/src/components/Dialog/Dialog.scss +268 -0
  168. package/src/components/Diff/Diff.scss +125 -0
  169. package/src/components/Divider/Divider.scss +22 -0
  170. package/src/components/Dock/Dock.scss +86 -0
  171. package/src/components/Field/Field.scss +38 -0
  172. package/src/components/Fieldset/Fieldset.scss +63 -0
  173. package/src/components/FileInput/FileInput.scss +66 -0
  174. package/src/components/Footer/Footer.scss +79 -0
  175. package/src/components/Grid/Grid.scss +86 -0
  176. package/src/components/Header/Header.scss +111 -0
  177. package/src/components/Heading/Heading.scss +7 -0
  178. package/src/components/Icon/Icon.scss +12 -0
  179. package/src/components/IconButton/IconButton.scss +6 -0
  180. package/src/components/Image/Image.scss +46 -0
  181. package/src/components/Indicator/Indicator.scss +48 -0
  182. package/src/components/Input/Input.scss +58 -0
  183. package/src/components/Key/Key.scss +48 -0
  184. package/src/components/Link/Link.scss +50 -0
  185. package/src/components/List/List.scss +62 -0
  186. package/src/components/Media/Media.scss +7 -0
  187. package/src/components/Menu/Menu.scss +91 -0
  188. package/src/components/Motion/Motion.scss +106 -0
  189. package/src/components/NumberField/NumberField.scss +44 -0
  190. package/src/components/OtpField/OtpField.scss +91 -0
  191. package/src/components/PageTransition/PageTransition.scss +197 -0
  192. package/src/components/Pagination/Pagination.scss +55 -0
  193. package/src/components/Popover/Popover.scss +13 -0
  194. package/src/components/Progress/Progress.scss +126 -0
  195. package/src/components/RadialProgress/RadialProgress.scss +65 -0
  196. package/src/components/Radio/Radio.scss +36 -0
  197. package/src/components/Rating/Rating.scss +121 -0
  198. package/src/components/ScrollSpy/ScrollSpy.scss +6 -0
  199. package/src/components/SegmentedControl/SegmentedControl.scss +107 -0
  200. package/src/components/Select/Select.scss +59 -0
  201. package/src/components/Sidebar/Sidebar.scss +88 -0
  202. package/src/components/Skeleton/Skeleton.scss +60 -0
  203. package/src/components/Slider/Slider.scss +96 -0
  204. package/src/components/Spacer/Spacer.scss +15 -0
  205. package/src/components/SpeedDial/SpeedDial.scss +109 -0
  206. package/src/components/Spinner/Spinner.scss +43 -0
  207. package/src/components/Stack/Stack.scss +57 -0
  208. package/src/components/Stat/Stat.scss +96 -0
  209. package/src/components/Status/Status.scss +60 -0
  210. package/src/components/Steps/Steps.scss +216 -0
  211. package/src/components/Swap/Swap.scss +62 -0
  212. package/src/components/Switch/Switch.scss +63 -0
  213. package/src/components/Table/Table.scss +183 -0
  214. package/src/components/Tabs/Tabs.scss +108 -0
  215. package/src/components/Text/Text.scss +34 -0
  216. package/src/components/TextRotate/TextRotate.scss +51 -0
  217. package/src/components/Textarea/Textarea.scss +56 -0
  218. package/src/components/ThemeProvider/ThemeProvider.scss +7 -0
  219. package/src/components/Tile/Tile.scss +23 -0
  220. package/src/components/Toast/Toast.scss +93 -0
  221. package/src/components/ToggleButton/ToggleButton.scss +23 -0
  222. package/src/components/Tooltip/Tooltip.scss +21 -0
  223. package/src/components/Type/Type.scss +35 -0
  224. package/src/components/Visibility/Visibility.scss +39 -0
  225. package/src/components/VisuallyHidden/VisuallyHidden.scss +17 -0
  226. package/src/styles/_breakpoint-vars.scss +16 -0
  227. package/src/styles/_config.scss +48 -0
  228. package/src/styles/_controls.scss +88 -0
  229. package/src/styles/_core.scss +4 -0
  230. package/src/styles/_effect.scss +51 -0
  231. package/src/styles/_floating.scss +141 -0
  232. package/src/styles/_kit.scss +1548 -0
  233. package/src/styles/_manifest.scss +670 -0
  234. package/src/styles/_mixins.scss +261 -0
  235. package/src/styles/_tones.scss +63 -0
  236. package/src/styles/_type-emit.scss +76 -0
  237. package/src/styles/_typography-vars.scss +8 -0
  238. package/src/styles/base.scss +80 -0
  239. package/src/styles/breakpoints.test.ts +73 -0
  240. package/src/styles/entryPoints.test.ts +68 -0
  241. package/src/styles/index.scss +93 -0
  242. package/src/styles/kit.test.ts +754 -0
  243. package/src/styles/public/_controls.scss +3 -0
  244. package/src/styles/public/_floating.scss +3 -0
  245. package/src/styles/public/_mixins.scss +5 -0
  246. package/src/styles/public/_tones.scss +4 -0
  247. package/themes/bevel.css +1077 -0
  248. package/themes/bevel.scss +1166 -0
  249. package/themes/candy.css +87 -0
  250. package/themes/candy.scss +32 -0
  251. package/themes/depth.css +123 -0
  252. package/themes/depth.scss +46 -0
  253. package/themes/extrude.css +219 -0
  254. package/themes/extrude.scss +255 -0
  255. package/themes/folio.css +986 -0
  256. package/themes/folio.scss +1047 -0
  257. package/themes/forest.css +87 -0
  258. package/themes/forest.scss +32 -0
  259. package/themes/gentle.css +66 -0
  260. package/themes/gentle.scss +39 -0
  261. package/themes/grape.css +87 -0
  262. package/themes/grape.scss +32 -0
  263. package/themes/greese.css +36 -0
  264. package/themes/greese.scss +21 -0
  265. package/themes/mono.css +87 -0
  266. package/themes/mono.scss +32 -0
  267. package/themes/ocean.css +87 -0
  268. package/themes/ocean.scss +32 -0
  269. package/themes/outline.css +127 -0
  270. package/themes/outline.scss +126 -0
  271. package/themes/pebble.css +65 -0
  272. package/themes/pebble.scss +69 -0
  273. package/themes/pocket.css +137 -0
  274. package/themes/pocket.scss +45 -0
  275. package/themes/ridge.css +927 -0
  276. package/themes/ridge.scss +998 -0
  277. package/themes/snappy.css +82 -0
  278. package/themes/snappy.scss +40 -0
  279. package/themes/soft.css +79 -0
  280. package/themes/soft.scss +84 -0
  281. package/themes/sunset.css +87 -0
  282. package/themes/sunset.scss +32 -0
  283. package/themes/ticket.css +960 -0
  284. package/themes/ticket.scss +1031 -0
  285. package/themes/tilt.css +148 -0
  286. package/themes/tilt.scss +169 -0
  287. package/themes/wipe.css +186 -0
  288. package/themes/wipe.scss +46 -0
@@ -0,0 +1,108 @@
1
+ @use '../../styles/mixins';
2
+
3
+ @layer greese.components {
4
+ .greese-Tabs {
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: var(--greese-space-4);
8
+
9
+ &[data-orientation='vertical'] {
10
+ flex-direction: row;
11
+ }
12
+ }
13
+
14
+ // Phones: tabs that don't fit scroll sideways rather than wrap or squash.
15
+ .greese-TabList {
16
+ display: flex;
17
+ gap: var(--greese-space-1);
18
+ overflow-x: auto;
19
+ overscroll-behavior-x: contain;
20
+ scroll-snap-type: x proximity;
21
+ scrollbar-width: none;
22
+ border-block-end: 1px solid var(--greese-color-border);
23
+
24
+ [data-orientation='vertical'] > & {
25
+ flex-direction: column;
26
+ flex-shrink: 0;
27
+ overflow: visible;
28
+ border-block-end: 0;
29
+ border-inline-end: 1px solid var(--greese-color-border);
30
+ }
31
+ }
32
+
33
+ .greese-Tab {
34
+ @include mixins.touch-target;
35
+
36
+ position: relative;
37
+ flex-shrink: 0;
38
+ min-block-size: 2.5rem;
39
+ padding-inline: var(--greese-space-3);
40
+ font: inherit;
41
+ font-weight: var(--greese-font-weight-medium);
42
+ color: var(--greese-color-fg-muted);
43
+ white-space: nowrap;
44
+ cursor: pointer;
45
+ scroll-snap-align: start;
46
+ background: none;
47
+ border: 0;
48
+ border-radius: var(--greese-corner-inset) var(--greese-corner-inset) 0 0;
49
+ box-shadow: inset 0 -2px 0 transparent;
50
+ transition:
51
+ color var(--greese-duration-fast) var(--greese-easing-standard),
52
+ background-color var(--greese-duration-fast) var(--greese-easing-standard),
53
+ box-shadow var(--greese-duration-fast) var(--greese-easing-standard);
54
+
55
+ @include mixins.focus-ring(-2px);
56
+
57
+ @include mixins.hover {
58
+ color: var(--greese-color-fg);
59
+ background-color: color-mix(in oklab, var(--greese-color-fg) 6%, transparent);
60
+ }
61
+
62
+ // The current tab is a tinted block over its underline, not a color change
63
+ // alone. Its fill and edge are hooks a theme reassigns (a color variant
64
+ // outlines it: `--greese-tab-current-edge: inset 0 0 0 1.5px …`).
65
+ &[aria-selected='true'] {
66
+ color: var(--greese-color-fg);
67
+ background-color: var(
68
+ --greese-tab-current-bg,
69
+ color-mix(in oklab, var(--greese-color-primary) 12%, transparent)
70
+ );
71
+ box-shadow: var(
72
+ --greese-tab-current-edge,
73
+ inset 0 -2px 0 var(--greese-color-primary)
74
+ );
75
+ }
76
+
77
+ &:disabled {
78
+ cursor: not-allowed;
79
+ opacity: 0.55;
80
+ }
81
+
82
+ [data-orientation='vertical'] & {
83
+ text-align: start;
84
+ border-radius: var(--greese-corner-inset) 0 0 var(--greese-corner-inset);
85
+
86
+ &[aria-selected='true'] {
87
+ box-shadow: var(
88
+ --greese-tab-current-edge,
89
+ inset -2px 0 0 var(--greese-color-primary)
90
+ );
91
+ }
92
+ }
93
+ }
94
+
95
+ .greese-TabPanel {
96
+ flex: 1 1 auto;
97
+ min-inline-size: 0;
98
+ border-radius: var(--greese-corner-inset);
99
+
100
+ @include mixins.focus-ring;
101
+
102
+ // A panel's content enters each time its tab is chosen (shown again, it
103
+ // restarts); the panel itself stays put.
104
+ @include mixins.content-entrance;
105
+ }
106
+
107
+ @include mixins.content-entrance-keyframes;
108
+ }
@@ -0,0 +1,34 @@
1
+ @use 'sass:list';
2
+ @use '../../styles/tones';
3
+
4
+ @layer greese.components {
5
+ .greese-Text {
6
+ margin: 0;
7
+ }
8
+
9
+ @each $weight in (regular, medium, semibold, bold) {
10
+ .greese-Text--#{$weight} {
11
+ font-weight: var(--greese-font-weight-#{$weight});
12
+ }
13
+ }
14
+
15
+ @each $tone, $pair in tones.$tones {
16
+ .greese-Text--#{$tone} {
17
+ color: list.nth($pair, 1);
18
+ }
19
+ }
20
+
21
+ .greese-Text--truncate {
22
+ overflow: hidden;
23
+ text-overflow: ellipsis;
24
+ white-space: nowrap;
25
+ }
26
+
27
+ .greese-Text--clamp {
28
+ display: -webkit-box;
29
+ overflow: hidden;
30
+ -webkit-box-orient: vertical;
31
+ -webkit-line-clamp: var(--greese-text-lines);
32
+ line-clamp: var(--greese-text-lines);
33
+ }
34
+ }
@@ -0,0 +1,51 @@
1
+ @use 'sass:math';
2
+ @use '../../styles/mixins';
3
+
4
+ // Keep in step with TEXT_ROTATE_MAX: each count compiles its own keyframes.
5
+ $max: 6;
6
+
7
+ @layer greese.components {
8
+ .greese-TextRotate {
9
+ display: inline-grid;
10
+ block-size: 1lh;
11
+ overflow: hidden;
12
+ vertical-align: bottom;
13
+ }
14
+
15
+ .greese-TextRotate-track {
16
+ display: flex;
17
+ flex-direction: column;
18
+ }
19
+
20
+ .greese-TextRotate-item {
21
+ block-size: 1lh;
22
+ white-space: nowrap;
23
+ }
24
+
25
+ // Each count gets keyframes that hold an item, then move up one line in
26
+ // the last fifth of its slot; the duplicate first item makes the wrap seamless.
27
+ @for $n from 2 through $max {
28
+ .greese-TextRotate--#{$n} .greese-TextRotate-track {
29
+ @include mixins.motion-safe {
30
+ animation: greese-textrotate-#{$n} var(--greese-textrotate-duration) infinite;
31
+ }
32
+ }
33
+
34
+ @keyframes greese-textrotate-#{$n} {
35
+ @for $i from 0 to $n {
36
+ $start: math.div($i, $n) * 100%;
37
+ $hold: math.div($i + 0.8, $n) * 100%;
38
+
39
+ #{$start},
40
+ #{$hold} {
41
+ animation-timing-function: var(--greese-easing-standard);
42
+ translate: 0 calc(-1lh * #{$i});
43
+ }
44
+ }
45
+
46
+ 100% {
47
+ translate: 0 calc(-1lh * #{$n});
48
+ }
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,56 @@
1
+ @use 'sass:map';
2
+ @use '../../styles/controls';
3
+
4
+ @layer greese.components {
5
+ // The frame draws the border and states; the textarea inside fills it.
6
+ .greese-Textarea {
7
+ @include controls.frame($focus-within: true);
8
+
9
+ display: flex;
10
+ inline-size: 100%;
11
+ }
12
+
13
+ .greese-Textarea-control {
14
+ flex: 1 1 auto;
15
+ min-inline-size: 0;
16
+ padding: var(--greese-space-2) var(--greese-textarea-padding);
17
+ font: inherit;
18
+ line-height: var(--greese-line-height-normal);
19
+ color: inherit;
20
+ resize: vertical;
21
+ background: none;
22
+ border: 0;
23
+ border-radius: inherit;
24
+ outline: none;
25
+
26
+ &::placeholder {
27
+ color: var(--greese-color-fg-muted);
28
+ opacity: 1;
29
+ }
30
+
31
+ &:disabled {
32
+ cursor: not-allowed;
33
+ }
34
+ }
35
+
36
+ .greese-Textarea--autosize .greese-Textarea-control {
37
+ // Lines from `rows` up to `maxRows`, in the text's own line height.
38
+ min-block-size: calc(var(--greese-textarea-rows) * 1lh + 2 * var(--greese-space-2));
39
+ max-block-size: calc(
40
+ var(--greese-textarea-max-rows, 1000) * 1lh + 2 * var(--greese-space-2)
41
+ );
42
+
43
+ @supports (field-sizing: content) {
44
+ field-sizing: content;
45
+ resize: none;
46
+ }
47
+ }
48
+
49
+ @each $size, $spec in controls.$sizes {
50
+ .greese-Textarea--size-#{$size} {
51
+ --greese-textarea-padding: #{map.get($spec, padding)};
52
+
53
+ @include controls.no-zoom-font(map.get($spec, font));
54
+ }
55
+ }
56
+ }
@@ -0,0 +1,7 @@
1
+ @layer greese.components {
2
+ // A scope, not a box: children lay out as if the wrapper were absent, while
3
+ // still inheriting its custom properties and color-scheme.
4
+ .greese-ThemeProvider {
5
+ display: contents;
6
+ }
7
+ }
@@ -0,0 +1,23 @@
1
+ @use '../../styles/mixins';
2
+
3
+ @layer greese.components {
4
+ // Padding is a default here, so the Box style props (utilities) override it.
5
+ .greese-Tile {
6
+ @include mixins.component-root;
7
+
8
+ min-inline-size: 0;
9
+ padding: var(--greese-tile-padding, var(--greese-space-3) var(--greese-space-4));
10
+ color: var(--greese-color-fg);
11
+ border: 1px solid var(--greese-color-border);
12
+ border-radius: var(--greese-corner-panel);
13
+ }
14
+
15
+ .greese-Tile--filled {
16
+ background-color: var(--greese-color-surface);
17
+ }
18
+
19
+ .greese-Tile--dashed {
20
+ border-style: dashed;
21
+ border-color: var(--greese-color-border-strong);
22
+ }
23
+ }
@@ -0,0 +1,93 @@
1
+ @use '../../styles/floating';
2
+ @use '../../styles/mixins';
3
+ @use '../../styles/tones';
4
+
5
+ @layer greese.components {
6
+ // The region itself is invisible: only the toasts are.
7
+ .greese-Toaster {
8
+ inset: auto 0 0;
9
+ inline-size: 100%;
10
+ max-inline-size: none;
11
+ padding: var(--greese-space-3);
12
+ padding-block-end: max(var(--greese-space-3), env(safe-area-inset-bottom));
13
+ margin: 0;
14
+ overflow: visible;
15
+ pointer-events: none;
16
+ background: none;
17
+ border: 0;
18
+
19
+ @include mixins.up(md) {
20
+ inset-inline: auto var(--greese-space-4);
21
+ inline-size: 24rem;
22
+ padding: var(--greese-space-4);
23
+ }
24
+ }
25
+
26
+ .greese-Toaster-list {
27
+ display: flex;
28
+ flex-direction: column;
29
+ gap: var(--greese-space-2);
30
+ padding: 0;
31
+ margin: 0;
32
+ list-style: none;
33
+ }
34
+
35
+ @include tones.classes(
36
+ 'greese-Toast',
37
+ 'greese-toast-tone',
38
+ (neutral, primary, secondary, tertiary, info, positive, warning, negative)
39
+ );
40
+
41
+ .greese-Toast {
42
+ @include floating.surface;
43
+
44
+ // The thick start edge in the toast's tone: a hook a shape theme draws
45
+ // inside the toast, where its clip would cut a border off.
46
+ --greese-toast-edge: var(--greese-toast-tone);
47
+
48
+ display: flex;
49
+ gap: var(--greese-space-2);
50
+ align-items: center;
51
+ padding: var(--greese-space-3);
52
+ padding-inline-start: var(--greese-space-4);
53
+ pointer-events: auto;
54
+ border-inline-start: 3px solid var(--greese-toast-edge);
55
+
56
+ // The theme's `toast` role (or a component's `motion()`); the base
57
+ // theme's rises a little as it fades in.
58
+ @include mixins.motion-safe {
59
+ @include mixins.role-entrance(toast, greese-toast-in, normal);
60
+ }
61
+ }
62
+
63
+ .greese-Toast--neutral {
64
+ --greese-toast-edge: var(--greese-color-border-strong);
65
+ }
66
+
67
+ .greese-Toast-body {
68
+ flex: 1 1 auto;
69
+ min-inline-size: 0;
70
+ }
71
+
72
+ .greese-Toast-title,
73
+ .greese-Toast-description {
74
+ margin: 0;
75
+ font-size: var(--greese-type-p3-font-size);
76
+ line-height: var(--greese-line-height-snug);
77
+ }
78
+
79
+ .greese-Toast-title {
80
+ font-weight: var(--greese-font-weight-semibold);
81
+ }
82
+
83
+ .greese-Toast-description {
84
+ color: var(--greese-color-fg-muted);
85
+ }
86
+
87
+ @keyframes greese-toast-in {
88
+ from {
89
+ opacity: 0;
90
+ translate: 0 0.75rem;
91
+ }
92
+ }
93
+ }
@@ -0,0 +1,23 @@
1
+ @layer greese.components {
2
+ // Pressed reads as the soft variant of the button's tone, whatever the
3
+ // resting variant: primary for the default neutral tone, or the tone given
4
+ // (tone="secondary" presses to a secondary tint).
5
+ .greese-ToggleButton[aria-pressed='true'] {
6
+ --greese-button-fg: var(--greese-button-tone);
7
+ --greese-button-bg: color-mix(in oklab, var(--greese-button-tone) 14%, transparent);
8
+ --greese-button-bg-hover: color-mix(
9
+ in oklab,
10
+ var(--greese-button-tone) 22%,
11
+ transparent
12
+ );
13
+ --greese-button-border: color-mix(
14
+ in oklab,
15
+ var(--greese-button-tone) 55%,
16
+ transparent
17
+ );
18
+ }
19
+
20
+ .greese-ToggleButton.greese-Button--neutral[aria-pressed='true'] {
21
+ --greese-button-tone: var(--greese-color-primary);
22
+ }
23
+ }
@@ -0,0 +1,21 @@
1
+ @use '../../styles/floating';
2
+
3
+ @layer greese.components {
4
+ .greese-Tooltip {
5
+ @include floating.anchored;
6
+ @include floating.enter-exit(':popover-open', 0 0, tooltip);
7
+
8
+ max-inline-size: min(18rem, 100vw - 2 * var(--greese-space-3));
9
+
10
+ // A line or two never needs to scroll; not being a scroller lets a
11
+ // theme's shape draw its border on the tooltip's own box.
12
+ overflow: visible;
13
+ padding: var(--greese-space-1) var(--greese-space-2);
14
+ font-size: var(--greese-type-caption-font-size);
15
+ line-height: var(--greese-line-height-snug);
16
+ color: var(--greese-color-canvas);
17
+ background-color: var(--greese-color-fg);
18
+ border: 0;
19
+ border-radius: var(--greese-corner-inset);
20
+ }
21
+ }
@@ -0,0 +1,35 @@
1
+ // The type variants as classes, for any element: `greese-Type--h2`. Each
2
+ // reads its own custom properties (`--greese-type-h2-font-size`…), which change
3
+ // across breakpoints (src/typography.ts), so the class never does. After
4
+ // Text and Heading, so a variant replaces their weight and line height.
5
+ @use 'sass:map';
6
+ @use '../../../dist/maps' as defaults;
7
+
8
+ @layer greese.components {
9
+ @each $variant in map.keys(defaults.$typography) {
10
+ .greese-Type--#{$variant} {
11
+ font-size: var(--greese-type-#{$variant}-font-size);
12
+ font-weight: var(--greese-type-#{$variant}-font-weight);
13
+ letter-spacing: var(--greese-type-#{$variant}-letter-spacing);
14
+ line-height: var(--greese-type-#{$variant}-line-height);
15
+
16
+ // Inherited unless the variant sets them.
17
+ @each $prop
18
+ in (
19
+ color,
20
+ font-family,
21
+ font-style,
22
+ text-transform,
23
+ font-feature-settings,
24
+ font-variation-settings,
25
+ font-stretch,
26
+ text-wrap,
27
+ word-spacing,
28
+ font-variant-numeric
29
+ )
30
+ {
31
+ #{$prop}: var(--greese-type-#{$variant}-#{$prop}, inherit);
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,39 @@
1
+ @use 'sass:map';
2
+ @use '../../styles/mixins';
3
+
4
+ @layer greese.components {
5
+ // Layout-neutral wrapper when not using asChild.
6
+ .greese-Visibility {
7
+ display: contents;
8
+ }
9
+ }
10
+
11
+ // Utilities, so hiding beats a component's own display (asChild on a Stack).
12
+ @layer greese.utilities {
13
+ @each $bp, $min in mixins.$breakpoints {
14
+ @if $min > 0 {
15
+ @include mixins.down($bp) {
16
+ .greese-Visibility--hide-below-#{$bp} {
17
+ display: none;
18
+ }
19
+ }
20
+
21
+ @include mixins.up($bp) {
22
+ .greese-Visibility--hide-from-#{$bp} {
23
+ display: none;
24
+ }
25
+ }
26
+
27
+ // Hide's range: from $bp up to (not including) each larger breakpoint.
28
+ @each $to, $max in mixins.$breakpoints {
29
+ @if $max > $min {
30
+ @media (width >= $min) and (width < $max) {
31
+ .greese-Visibility--hide-#{$bp}-to-#{$to} {
32
+ display: none;
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,17 @@
1
+ @use '../../styles/mixins';
2
+
3
+ @layer greese.components {
4
+ .greese-VisuallyHidden {
5
+ @include mixins.component-root;
6
+
7
+ position: absolute;
8
+ inline-size: 1px;
9
+ block-size: 1px;
10
+ padding: 0;
11
+ margin: -1px;
12
+ overflow: hidden;
13
+ white-space: nowrap;
14
+ border: 0;
15
+ clip-path: inset(50%);
16
+ }
17
+ }
@@ -0,0 +1,16 @@
1
+ // Built with your own breakpoints (changed values or extra keys): the tokens
2
+ // declare the defaults' `--greese-breakpoint-*` custom properties, so
3
+ // redeclare every one with the configured values. Nothing is emitted for the
4
+ // defaults.
5
+ @use 'config';
6
+ @use '../../dist/maps' as defaults;
7
+
8
+ @if config.$breakpoints != defaults.$breakpoints {
9
+ @layer greese.tokens {
10
+ :root {
11
+ @each $key, $min in config.$breakpoints {
12
+ --greese-breakpoint-#{$key}: #{$min};
13
+ }
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,48 @@
1
+ // The configurable part of greese ui's SCSS: the breakpoints. They're fixed
2
+ // when the stylesheet is built (media queries can't read variables), so you
3
+ // change them by compiling with your own, smallest first. Values may change and
4
+ // keys may be added, but xs/sm/md/lg/xl stay, because components use them:
5
+ // @use 'pkg:@greese/ui/scss' with (
6
+ // $breakpoints: (xs: 0px, sm: 480px, tablet: 700px, md: 768px, lg: 1024px, xl: 1440px)
7
+ // );
8
+ // The type system's values can be set the same way (`$typography`, shaped like
9
+ // the defaults: variant -> base | breakpoint -> prop: value; see Typography).
10
+ // Every key gets responsive classes (`greese-Stack--tablet-gap-3`) and a custom
11
+ // property, `--greese-breakpoint-tablet: 700px`. Then call
12
+ // configureBreakpoints({ sm: 480, tablet: 700, … }) so useBreakpoint() and
13
+ // friends agree, and for TypeScript add the key to `BreakpointKeys`.
14
+ @use 'sass:map';
15
+ @use 'sass:string';
16
+ @use '../../dist/maps' as defaults;
17
+
18
+ $breakpoints: defaults.$breakpoints !default;
19
+ $typography: defaults.$typography !default;
20
+ $space-keys: defaults.$space-keys;
21
+
22
+ @each $key in map.keys(defaults.$breakpoints) {
23
+ @if not map.has-key($breakpoints, $key) {
24
+ @error 'greese ui $breakpoints must keep the key `#{$key}` (components use #{map.keys(defaults.$breakpoints)}); you can add keys and change values. Got #{map.keys($breakpoints)}.';
25
+ }
26
+ }
27
+
28
+ // 0 and 0px differ in Sass, and the unit is the point here.
29
+ // stylelint-disable-next-line length-zero-no-unit
30
+ @if map.get($breakpoints, xs) != 0px {
31
+ @error 'greese ui $breakpoints: `xs` must be 0, got #{map.get($breakpoints, xs)}.';
32
+ }
33
+
34
+ // Mobile-first rules are emitted in map order, so the map must run smallest
35
+ // to largest, with no two keys sharing a value.
36
+ $_previous: -1px;
37
+
38
+ @each $key, $min in $breakpoints {
39
+ @if string.index('#{$key}', '-') {
40
+ @error 'greese ui $breakpoints: key `#{$key}` must be one word, without dashes, as it goes into class and variable names. Quote a key that starts with a digit (\'2xl\').';
41
+ }
42
+
43
+ @if $min <= $_previous {
44
+ @error 'greese ui $breakpoints must increase from the first key to the last, but `#{$key}` (#{$min}) does not exceed the one before it.';
45
+ }
46
+
47
+ $_previous: $min;
48
+ }
@@ -0,0 +1,88 @@
1
+ // Shared look and sizing for form controls (Input, Select, Textarea, …) and
2
+ // buttons, so every control in a row lines up at the same size.
3
+ @use 'mixins';
4
+
5
+ /// Control size scale: block size, inline padding, font size.
6
+ $sizes: (
7
+ xs: (
8
+ height: 1rem,
9
+ padding: var(--greese-space-1),
10
+ font: var(--greese-type-p3-font-size),
11
+ ),
12
+ sm: (
13
+ height: 2rem,
14
+ padding: var(--greese-space-3),
15
+ font: var(--greese-type-p3-font-size),
16
+ ),
17
+ md: (
18
+ height: 2.5rem,
19
+ padding: var(--greese-space-3),
20
+ font: var(--greese-type-p2-font-size),
21
+ ),
22
+ lg: (
23
+ height: 3rem,
24
+ padding: var(--greese-space-4),
25
+ font: var(--greese-type-p2-font-size),
26
+ ),
27
+ xl: (
28
+ height: 4rem,
29
+ padding: var(--greese-space-4),
30
+ font: var(--greese-type-p1-font-size),
31
+ ),
32
+ );
33
+
34
+ /// iOS Safari zooms the page when a focused control's text is under 16px.
35
+ /// Touch devices therefore never go below 1rem.
36
+ @mixin no-zoom-font($font) {
37
+ font-size: $font;
38
+
39
+ @media (pointer: coarse) {
40
+ font-size: max(1rem, #{$font});
41
+ }
42
+ }
43
+
44
+ /// Border, background, focus ring and state styling for a text-like control.
45
+ /// Apply to the element that draws the frame; `$focus-within` when the real
46
+ /// input sits inside it (Input with adornments, Select).
47
+ @mixin frame($focus-within: false) {
48
+ @include mixins.component-root;
49
+
50
+ color: var(--greese-color-fg);
51
+ background-color: var(--greese-color-canvas);
52
+ border: 1px solid var(--greese-color-border-strong);
53
+ border-radius: var(--greese-corner-field);
54
+ transition:
55
+ border-color var(--greese-duration-fast) var(--greese-easing-standard),
56
+ box-shadow var(--greese-duration-fast) var(--greese-easing-standard);
57
+
58
+ @include mixins.hover {
59
+ border-color: var(--greese-color-fg-muted);
60
+ }
61
+
62
+ @if $focus-within {
63
+ &:has(:focus-visible) {
64
+ @include focused;
65
+ }
66
+ } @else {
67
+ &:focus-visible {
68
+ @include focused;
69
+ }
70
+ }
71
+
72
+ &[aria-invalid='true'],
73
+ &[data-invalid] {
74
+ border-color: var(--greese-color-negative);
75
+ }
76
+
77
+ &:disabled,
78
+ &[data-disabled] {
79
+ cursor: not-allowed;
80
+ opacity: 0.55;
81
+ }
82
+ }
83
+
84
+ @mixin focused {
85
+ border-color: var(--greese-color-focus-ring);
86
+ outline: 2px solid var(--greese-color-focus-ring);
87
+ outline-offset: -1px;
88
+ }
@@ -0,0 +1,4 @@
1
+ // What every component needs: the layer order, the tokens and the type
2
+ // system. The whole stylesheet and css/core.css both start from this.
3
+ @use '../../dist/tokens-base';
4
+ @use 'typography-vars';