@greese/ui 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -14
- package/dist/_maps.scss +1 -1
- package/dist/_tokens-base.scss +30 -6
- package/dist/_tokens.scss +31 -2
- package/dist/_utilities-table.scss +1615 -0
- package/dist/clipboard.d.ts +18 -0
- package/dist/clipboard.js +62 -0
- package/dist/css/Button.css +2 -2
- package/dist/css/Carousel.css +145 -47
- package/dist/css/Checkbox.css +2 -2
- package/dist/css/Chip.css +38 -8
- package/dist/css/ChoiceGroup.css +42 -1
- package/dist/css/Collapsible.css +1 -0
- package/dist/css/ColorPicker.css +84 -0
- package/dist/css/Combobox.css +2 -2
- package/dist/css/Dialog.css +24 -22
- package/dist/css/EditableField.css +219 -0
- package/dist/css/Input.css +11 -2
- package/dist/css/Menu.css +9 -0
- package/dist/css/NumberField.css +53 -8
- package/dist/css/NumberStepper.css +9 -0
- package/dist/css/OtpField.css +1 -1
- package/dist/css/PageTransition.css +12 -0
- package/dist/css/Radio.css +2 -2
- package/dist/css/ScrollCarousel.css +225 -0
- package/dist/css/SegmentedControl.css +2 -2
- package/dist/css/Select.css +3 -2
- package/dist/css/Slider.css +45 -5
- package/dist/css/Switch.css +6 -6
- package/dist/css/Text.css +14 -14
- package/dist/css/Textarea.css +1 -1
- package/dist/css/core.css +36 -6
- package/dist/css/resets.css +162 -0
- package/dist/css.d.ts +2 -0
- package/dist/css.js +2 -0
- package/dist/greese.css +990 -138
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/scss/components/_Accordion.scss +2 -0
- package/dist/scss/components/_ActionSelect.scss +2 -0
- package/dist/scss/components/_Alert.scss +2 -0
- package/dist/scss/components/_AppBar.scss +2 -0
- package/dist/scss/components/_AspectRatio.scss +2 -0
- package/dist/scss/components/_AutoLayout.scss +2 -0
- package/dist/scss/components/_Avatar.scss +2 -0
- package/dist/scss/components/_Badge.scss +2 -0
- package/dist/scss/components/_Box.scss +2 -0
- package/dist/scss/components/_Breadcrumbs.scss +2 -0
- package/dist/scss/components/_Button.scss +2 -0
- package/dist/scss/components/_ButtonGroup.scss +2 -0
- package/dist/scss/components/_Card.scss +2 -0
- package/dist/scss/components/_Carousel.scss +2 -0
- package/dist/scss/components/_Center.scss +2 -0
- package/dist/scss/components/_ChatBubble.scss +2 -0
- package/dist/scss/components/_Checkbox.scss +2 -0
- package/dist/scss/components/_Chip.scss +2 -0
- package/dist/scss/components/_ChoiceGroup.scss +2 -0
- package/dist/scss/components/_Code.scss +2 -0
- package/dist/scss/components/_Collapsible.scss +2 -0
- package/dist/scss/components/_ColorPicker.scss +2 -0
- package/dist/scss/components/_Combobox.scss +2 -0
- package/dist/scss/components/_Container.scss +2 -0
- package/dist/scss/components/_Countdown.scss +2 -0
- package/dist/scss/components/_DateField.scss +2 -0
- package/dist/scss/components/_Dialog.scss +2 -0
- package/dist/scss/components/_Diff.scss +2 -0
- package/dist/scss/components/_Divider.scss +2 -0
- package/dist/scss/components/_Dock.scss +2 -0
- package/dist/scss/components/_EditableField.scss +2 -0
- package/dist/scss/components/_Field.scss +2 -0
- package/dist/scss/components/_Fieldset.scss +2 -0
- package/dist/scss/components/_FileInput.scss +2 -0
- package/dist/scss/components/_Footer.scss +2 -0
- package/dist/scss/components/_Grid.scss +2 -0
- package/dist/scss/components/_Header.scss +2 -0
- package/dist/scss/components/_Heading.scss +2 -0
- package/dist/scss/components/_Icon.scss +2 -0
- package/dist/scss/components/_IconButton.scss +2 -0
- package/dist/scss/components/_Image.scss +2 -0
- package/dist/scss/components/_Indicator.scss +2 -0
- package/dist/scss/components/_Input.scss +2 -0
- package/dist/scss/components/_Key.scss +2 -0
- package/dist/scss/components/_Link.scss +2 -0
- package/dist/scss/components/_List.scss +2 -0
- package/dist/scss/components/_Media.scss +2 -0
- package/dist/scss/components/_Menu.scss +2 -0
- package/dist/scss/components/_Motion.scss +2 -0
- package/dist/scss/components/_NumberField.scss +2 -0
- package/dist/scss/components/_NumberStepper.scss +2 -0
- package/dist/scss/components/_OtpField.scss +2 -0
- package/dist/scss/components/_PageTransition.scss +2 -0
- package/dist/scss/components/_Pagination.scss +2 -0
- package/dist/scss/components/_Popover.scss +2 -0
- package/dist/scss/components/_Progress.scss +2 -0
- package/dist/scss/components/_RadialProgress.scss +2 -0
- package/dist/scss/components/_Radio.scss +2 -0
- package/dist/scss/components/_Rating.scss +2 -0
- package/dist/scss/components/_ScrollCarousel.scss +2 -0
- package/dist/scss/components/_ScrollSpy.scss +2 -0
- package/dist/scss/components/_SegmentedControl.scss +2 -0
- package/dist/scss/components/_Select.scss +2 -0
- package/dist/scss/components/_Sidebar.scss +2 -0
- package/dist/scss/components/_Skeleton.scss +2 -0
- package/dist/scss/components/_Slider.scss +2 -0
- package/dist/scss/components/_Spacer.scss +2 -0
- package/dist/scss/components/_SpeedDial.scss +2 -0
- package/dist/scss/components/_Spinner.scss +2 -0
- package/dist/scss/components/_Stack.scss +2 -0
- package/dist/scss/components/_Stat.scss +2 -0
- package/dist/scss/components/_Status.scss +2 -0
- package/dist/scss/components/_Steps.scss +2 -0
- package/dist/scss/components/_Swap.scss +2 -0
- package/dist/scss/components/_Switch.scss +2 -0
- package/dist/scss/components/_Table.scss +2 -0
- package/dist/scss/components/_Tabs.scss +2 -0
- package/dist/scss/components/_Text.scss +2 -0
- package/dist/scss/components/_TextRotate.scss +2 -0
- package/dist/scss/components/_Textarea.scss +2 -0
- package/dist/scss/components/_ThemeProvider.scss +2 -0
- package/dist/scss/components/_Tile.scss +2 -0
- package/dist/scss/components/_Toast.scss +2 -0
- package/dist/scss/components/_ToggleButton.scss +2 -0
- package/dist/scss/components/_Tooltip.scss +2 -0
- package/dist/scss/components/_Type.scss +2 -0
- package/dist/scss/components/_Visibility.scss +2 -0
- package/dist/scss/components/_VisuallyHidden.scss +2 -0
- package/dist/shapes.d.ts +12 -1
- package/dist/shapes.js +11 -10
- package/dist/style-manifest.json +18837 -132
- package/dist/theme.js +6 -1
- package/dist/themeFiles/index.d.ts +9 -0
- package/dist/themeFiles/index.js +9 -0
- package/dist/themeFiles/scssModule.d.ts +100 -0
- package/dist/themeFiles/scssModule.js +384 -0
- package/dist/themeFiles/spec.d.ts +198 -0
- package/dist/themeFiles/spec.js +877 -0
- package/dist/tokens.css +30 -1
- package/dist/typography.js +1 -1
- package/dist/utilities.css +435 -0
- package/dist/utilities.d.ts +8 -0
- package/dist/utilities.js +75 -0
- package/package.json +20 -1
- package/src/components/AutoLayout/AutoLayout.scss +2 -26
- package/src/components/Carousel/Carousel.scss +122 -126
- package/src/components/Checkbox/Checkbox.scss +2 -2
- package/src/components/Chip/Chip.scss +63 -8
- package/src/components/ChoiceGroup/ChoiceGroup.scss +19 -1
- package/src/components/Collapsible/Collapsible.scss +3 -0
- package/src/components/ColorPicker/ColorPicker.scss +95 -0
- package/src/components/Combobox/Combobox.scss +4 -2
- package/src/components/Dialog/Dialog.scss +24 -7
- package/src/components/EditableField/EditableField.scss +275 -0
- package/src/components/Grid/Grid.scss +2 -70
- package/src/components/Input/Input.scss +29 -0
- package/src/components/Menu/Menu.scss +18 -0
- package/src/components/NumberField/NumberField.scss +56 -9
- package/src/components/NumberStepper/NumberStepper.scss +13 -0
- package/src/components/PageTransition/PageTransition.scss +29 -0
- package/src/components/Radio/Radio.scss +2 -2
- package/src/components/ScrollCarousel/ScrollCarousel.scss +142 -0
- package/src/components/Select/Select.scss +4 -0
- package/src/components/Slider/Slider.scss +51 -6
- package/src/components/Stack/Stack.scss +2 -48
- package/src/components/Switch/Switch.scss +9 -6
- package/src/components/Text/Text.scss +5 -2
- package/src/styles/_breakpoint-vars.scss +17 -11
- package/src/styles/_controls.scss +2 -2
- package/src/styles/_core.scss +1 -0
- package/src/styles/_kit.scss +483 -56
- package/src/styles/_layout-props.scss +197 -0
- package/src/styles/_manifest.scss +55 -25
- package/src/styles/_mixins.scss +53 -15
- package/src/styles/_slides.scss +112 -0
- package/src/styles/_utilities.scss +104 -0
- package/src/styles/breakpoints.test.ts +21 -1
- package/src/styles/entryPoints.test.ts +25 -2
- package/src/styles/index.scss +3 -1
- package/src/styles/kit.test.ts +171 -1
- package/src/styles/public/_breakpoints.scss +43 -0
- package/src/styles/public/_slides.scss +3 -0
- package/src/styles/public/_utilities.scss +3 -0
- package/src/styles/resets.scss +7 -0
- package/src/styles/utilities.test.ts +39 -0
- package/themes/bevel.css +187 -187
- package/themes/bevel.scss +960 -958
- package/themes/candy.css +87 -0
- package/themes/candy.scss +32 -0
- package/themes/extrude.css +42 -42
- package/themes/folio.css +200 -200
- package/themes/folio.scss +880 -878
- package/themes/forest.css +87 -0
- package/themes/forest.scss +32 -0
- package/themes/grape.css +87 -0
- package/themes/grape.scss +32 -0
- package/themes/greese.css +36 -0
- package/themes/greese.scss +21 -0
- package/themes/mono.css +87 -0
- package/themes/mono.scss +32 -0
- package/themes/ocean.css +87 -0
- package/themes/ocean.scss +32 -0
- package/themes/outline.css +18 -18
- package/themes/pebble.css +8 -8
- package/themes/ridge.css +188 -188
- package/themes/ridge.scss +820 -818
- package/themes/soft.css +11 -11
- package/themes/sunset.css +87 -0
- package/themes/sunset.scss +32 -0
- package/themes/ticket.css +180 -180
- package/themes/ticket.scss +881 -879
- package/themes/tilt.css +25 -25
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use '../../styles/controls';
|
|
3
|
+
@use '../../styles/mixins';
|
|
4
|
+
|
|
5
|
+
// A color picker's swatch paints literal colors, whatever the theme: the
|
|
6
|
+
// checkerboard behind a transparent color reads as "nothing here", not as a
|
|
7
|
+
// surface, so it does not follow the palette.
|
|
8
|
+
/* stylelint-disable color-no-hex */
|
|
9
|
+
$checker: repeating-conic-gradient(#c8ccd2 0% 25%, #fff 0% 50%) 0 0 / 0.5rem 0.5rem;
|
|
10
|
+
|
|
11
|
+
@layer greese.components {
|
|
12
|
+
.greese-EditableField {
|
|
13
|
+
--greese-editablefield-dial: 2.25rem;
|
|
14
|
+
|
|
15
|
+
@include mixins.component-root;
|
|
16
|
+
|
|
17
|
+
display: flex;
|
|
18
|
+
gap: var(--greese-space-2);
|
|
19
|
+
align-items: center;
|
|
20
|
+
min-inline-size: 0;
|
|
21
|
+
|
|
22
|
+
&[data-disabled] {
|
|
23
|
+
opacity: 0.55;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// A property row: the name on one side, the control on the other, so a
|
|
28
|
+
// column of fields lines up down the panel.
|
|
29
|
+
.greese-EditableField--row {
|
|
30
|
+
justify-content: space-between;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.greese-EditableField--column {
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
align-items: stretch;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.greese-EditableField-label {
|
|
39
|
+
flex: none;
|
|
40
|
+
color: var(--greese-color-fg-muted);
|
|
41
|
+
|
|
42
|
+
// The name must not push the control out of a narrow panel.
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
text-overflow: ellipsis;
|
|
45
|
+
white-space: nowrap;
|
|
46
|
+
|
|
47
|
+
.greese-EditableField--column > & {
|
|
48
|
+
align-self: start;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Every control sits on the other side of the row and takes the slack.
|
|
53
|
+
.greese-EditableField-control {
|
|
54
|
+
flex: 1 1 auto;
|
|
55
|
+
min-inline-size: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// A checkbox, switch or dial is its own size: stretching one would leave the
|
|
59
|
+
// hit target floating in a box of empty space.
|
|
60
|
+
.greese-EditableField--checkbox > .greese-EditableField-control,
|
|
61
|
+
.greese-EditableField--switch > .greese-EditableField-control,
|
|
62
|
+
.greese-EditableField--radio > .greese-EditableField-control,
|
|
63
|
+
.greese-EditableField--segmented > .greese-EditableField-control {
|
|
64
|
+
flex: 0 0 auto;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.greese-EditableField-number,
|
|
68
|
+
.greese-EditableField-range,
|
|
69
|
+
.greese-EditableField-knob {
|
|
70
|
+
display: flex;
|
|
71
|
+
gap: var(--greese-space-2);
|
|
72
|
+
align-items: center;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.greese-EditableField-number > .greese-NumberField,
|
|
76
|
+
.greese-EditableField-range > .greese-Slider,
|
|
77
|
+
.greese-EditableField-knob > .greese-NumberField {
|
|
78
|
+
flex: 1;
|
|
79
|
+
min-inline-size: 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// The × that empties the field: a small, muted target inside its end.
|
|
83
|
+
.greese-EditableField-clear {
|
|
84
|
+
@include mixins.touch-target;
|
|
85
|
+
|
|
86
|
+
position: relative;
|
|
87
|
+
display: inline-grid;
|
|
88
|
+
flex: none;
|
|
89
|
+
place-items: center;
|
|
90
|
+
inline-size: 1.25rem;
|
|
91
|
+
block-size: 1.25rem;
|
|
92
|
+
padding: 0;
|
|
93
|
+
color: var(--greese-color-fg-muted);
|
|
94
|
+
cursor: pointer;
|
|
95
|
+
background: none;
|
|
96
|
+
border: 0;
|
|
97
|
+
border-radius: var(--greese-corner-round);
|
|
98
|
+
|
|
99
|
+
@include mixins.hover {
|
|
100
|
+
color: var(--greese-color-fg);
|
|
101
|
+
background-color: color-mix(in oklab, var(--greese-color-fg) 8%, transparent);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
> svg {
|
|
105
|
+
inline-size: 0.75rem;
|
|
106
|
+
block-size: 0.75rem;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// A textarea's × sits in its top end corner, over the text's margin.
|
|
111
|
+
.greese-EditableField-textarea {
|
|
112
|
+
position: relative;
|
|
113
|
+
|
|
114
|
+
> .greese-EditableField-clear {
|
|
115
|
+
position: absolute;
|
|
116
|
+
inset-block-start: var(--greese-space-1);
|
|
117
|
+
inset-inline-end: var(--greese-space-1);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
&:has(> .greese-EditableField-clear) .greese-Textarea-control {
|
|
121
|
+
padding-inline-end: 1.75rem;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.greese-EditableField-unit,
|
|
126
|
+
.greese-EditableField-value {
|
|
127
|
+
flex: none;
|
|
128
|
+
font-variant-numeric: tabular-nums;
|
|
129
|
+
color: var(--greese-color-fg-muted);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.greese-EditableField-value {
|
|
133
|
+
min-inline-size: 3ch;
|
|
134
|
+
text-align: end;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// The color swatch that opens the picker. It takes the slack like a text
|
|
138
|
+
// field does, so the color a field holds is as easy to see and to hit as
|
|
139
|
+
// the value in the row above it. The floor is a hit target: the button has
|
|
140
|
+
// no content, so nothing else would stop it collapsing to a sliver.
|
|
141
|
+
.greese-EditableField-swatch {
|
|
142
|
+
inline-size: 100%;
|
|
143
|
+
padding: 0;
|
|
144
|
+
cursor: pointer;
|
|
145
|
+
background:
|
|
146
|
+
linear-gradient(
|
|
147
|
+
var(--greese-editablefield-swatch),
|
|
148
|
+
var(--greese-editablefield-swatch)
|
|
149
|
+
),
|
|
150
|
+
$checker;
|
|
151
|
+
border: 0;
|
|
152
|
+
border-radius: var(--greese-corner-inset);
|
|
153
|
+
box-shadow: inset 0 0 0 1px var(--greese-color-border-strong);
|
|
154
|
+
|
|
155
|
+
// As tall as the field's other controls at its size, on every pointer;
|
|
156
|
+
// a coarse pointer gets a 44px hit area around it instead.
|
|
157
|
+
position: relative;
|
|
158
|
+
min-inline-size: var(--greese-editablefield-height, 1.75rem);
|
|
159
|
+
block-size: var(--greese-editablefield-height, 1.75rem);
|
|
160
|
+
|
|
161
|
+
@include mixins.touch-target;
|
|
162
|
+
|
|
163
|
+
&:focus-visible {
|
|
164
|
+
outline: 2px solid var(--greese-color-focus-ring);
|
|
165
|
+
outline-offset: 2px;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
&:disabled {
|
|
169
|
+
cursor: not-allowed;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// No color at all, and a mixed selection, are different states: a slash
|
|
173
|
+
// for the one that is set to nothing, a dim fill for the one that has no
|
|
174
|
+
// single answer yet.
|
|
175
|
+
&[data-none] {
|
|
176
|
+
background:
|
|
177
|
+
linear-gradient(
|
|
178
|
+
to top right,
|
|
179
|
+
transparent calc(50% - 1px),
|
|
180
|
+
var(--greese-color-negative) calc(50% - 1px),
|
|
181
|
+
var(--greese-color-negative) calc(50% + 1px),
|
|
182
|
+
transparent calc(50% + 1px)
|
|
183
|
+
),
|
|
184
|
+
var(--greese-color-surface);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
&[data-mixed] {
|
|
188
|
+
background: var(--greese-color-track);
|
|
189
|
+
box-shadow: inset 0 0 0 1px var(--greese-color-border-strong);
|
|
190
|
+
opacity: 0.7;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// The picker's popover, and the "No color" button under it.
|
|
195
|
+
// `display` is scoped to the open state on purpose. An author `display`
|
|
196
|
+
// beats the UA's `[popover]:not(:popover-open) { display: none }`, so
|
|
197
|
+
// declaring it unconditionally leaves the closed popover laid out and
|
|
198
|
+
// hit-testable — invisible, because the exit state sets `opacity: 0`, while
|
|
199
|
+
// still swallowing clicks meant for whatever is under it.
|
|
200
|
+
.greese-EditableField-picker:popover-open {
|
|
201
|
+
display: grid;
|
|
202
|
+
gap: var(--greese-space-3);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.greese-EditableField-none {
|
|
206
|
+
padding: var(--greese-space-2);
|
|
207
|
+
font: inherit;
|
|
208
|
+
color: var(--greese-color-fg);
|
|
209
|
+
cursor: pointer;
|
|
210
|
+
background: var(--greese-color-surface);
|
|
211
|
+
border: 1px solid var(--greese-color-border);
|
|
212
|
+
border-radius: var(--greese-corner-inset);
|
|
213
|
+
|
|
214
|
+
&:hover {
|
|
215
|
+
background: var(--greese-color-track);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
&:focus-visible {
|
|
219
|
+
outline: 2px solid var(--greese-color-focus-ring);
|
|
220
|
+
outline-offset: 2px;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// The dial: a circle whose dot shows where it points.
|
|
225
|
+
.greese-EditableField-dial {
|
|
226
|
+
position: relative;
|
|
227
|
+
flex: none;
|
|
228
|
+
inline-size: var(--greese-editablefield-dial);
|
|
229
|
+
block-size: var(--greese-editablefield-dial);
|
|
230
|
+
cursor: grab;
|
|
231
|
+
background: var(--greese-color-track);
|
|
232
|
+
border: 1px solid var(--greese-color-border);
|
|
233
|
+
border-radius: var(--greese-corner-round);
|
|
234
|
+
|
|
235
|
+
// Turning the dial must not scroll the page under a finger.
|
|
236
|
+
touch-action: none;
|
|
237
|
+
|
|
238
|
+
&:focus-visible {
|
|
239
|
+
outline: 2px solid var(--greese-color-focus-ring);
|
|
240
|
+
outline-offset: 2px;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
&[aria-disabled='true'] {
|
|
244
|
+
cursor: not-allowed;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.greese-EditableField-dialDot {
|
|
249
|
+
position: absolute;
|
|
250
|
+
inset: 0;
|
|
251
|
+
display: block;
|
|
252
|
+
|
|
253
|
+
// The dot rides at the top of the circle and the whole layer rotates, so
|
|
254
|
+
// one angle drives it with no trigonometry in JavaScript.
|
|
255
|
+
rotate: var(--greese-editablefield-angle, 0deg);
|
|
256
|
+
|
|
257
|
+
&::after {
|
|
258
|
+
position: absolute;
|
|
259
|
+
inset-block-start: 0.125rem;
|
|
260
|
+
inset-inline-start: 50%;
|
|
261
|
+
inline-size: 0.375rem;
|
|
262
|
+
block-size: 0.375rem;
|
|
263
|
+
content: '';
|
|
264
|
+
background: var(--greese-color-primary);
|
|
265
|
+
border-radius: var(--greese-corner-round);
|
|
266
|
+
translate: -50% 0;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
@each $size, $spec in controls.$sizes {
|
|
271
|
+
.greese-EditableField--size-#{$size} {
|
|
272
|
+
--greese-editablefield-height: #{map.get($spec, height)};
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
@@ -1,29 +1,4 @@
|
|
|
1
|
-
@use '
|
|
2
|
-
@use '../../styles/mixins';
|
|
3
|
-
|
|
4
|
-
$column-counts: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
|
|
5
|
-
|
|
6
|
-
@function column-tokens() {
|
|
7
|
-
$map: ();
|
|
8
|
-
|
|
9
|
-
@each $n in $column-counts {
|
|
10
|
-
$map: map.set($map, $n, repeat(#{$n}, minmax(0, 1fr)));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
@return $map;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
@function size-tokens() {
|
|
17
|
-
$map: (
|
|
18
|
-
full: #{'1 / -1'},
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
@each $n in $column-counts {
|
|
22
|
-
$map: map.set($map, $n, span #{$n} / span #{$n});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@return $map;
|
|
26
|
-
}
|
|
1
|
+
@use '../../styles/layout-props';
|
|
27
2
|
|
|
28
3
|
@layer greese.components {
|
|
29
4
|
// Every Grid can be a cell; `container` makes it a grid too.
|
|
@@ -39,48 +14,5 @@ $column-counts: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
|
|
|
39
14
|
container-type: inline-size;
|
|
40
15
|
}
|
|
41
16
|
|
|
42
|
-
@include
|
|
43
|
-
'greese-Grid',
|
|
44
|
-
'columns',
|
|
45
|
-
grid-template-columns,
|
|
46
|
-
column-tokens()
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
// After `columns`, so it wins where both apply.
|
|
50
|
-
@include mixins.responsive-prop(
|
|
51
|
-
'greese-Grid',
|
|
52
|
-
'min-child',
|
|
53
|
-
grid-template-columns,
|
|
54
|
-
$template: 'repeat(auto-fill, minmax(min(VALUE, 100%), 1fr))'
|
|
55
|
-
);
|
|
56
|
-
@include mixins.responsive-prop('greese-Grid', 'gap', gap, mixins.space-tokens());
|
|
57
|
-
@include mixins.responsive-prop(
|
|
58
|
-
'greese-Grid',
|
|
59
|
-
'align',
|
|
60
|
-
align-items,
|
|
61
|
-
(
|
|
62
|
-
start: start,
|
|
63
|
-
center: center,
|
|
64
|
-
end: end,
|
|
65
|
-
stretch: stretch,
|
|
66
|
-
)
|
|
67
|
-
);
|
|
68
|
-
@include mixins.responsive-prop(
|
|
69
|
-
'greese-Grid',
|
|
70
|
-
'justify',
|
|
71
|
-
justify-items,
|
|
72
|
-
(
|
|
73
|
-
start: start,
|
|
74
|
-
center: center,
|
|
75
|
-
end: end,
|
|
76
|
-
stretch: stretch,
|
|
77
|
-
)
|
|
78
|
-
);
|
|
79
|
-
@include mixins.responsive-prop(
|
|
80
|
-
'greese-Grid',
|
|
81
|
-
'size',
|
|
82
|
-
grid-column,
|
|
83
|
-
size-tokens(),
|
|
84
|
-
$container-scope: '.greese-Grid--queries >'
|
|
85
|
-
);
|
|
17
|
+
@include layout-props.grid;
|
|
86
18
|
}
|
|
@@ -8,7 +8,16 @@
|
|
|
8
8
|
display: flex;
|
|
9
9
|
gap: var(--greese-space-2);
|
|
10
10
|
align-items: center;
|
|
11
|
+
|
|
12
|
+
// Fills whatever it sits in — a Field, a table cell, a flex row.
|
|
11
13
|
inline-size: 100%;
|
|
14
|
+
|
|
15
|
+
// …but imposes no floor of its own. A flex item's automatic minimum size is
|
|
16
|
+
// its content's min-content width, and an `<input>`'s min-content width is
|
|
17
|
+
// whatever `size` says — about twenty characters by default, a number
|
|
18
|
+
// nobody chose. That is what stopped a text field from ever being narrower
|
|
19
|
+
// than twenty characters, however little the layout had to give it.
|
|
20
|
+
min-inline-size: 0;
|
|
12
21
|
min-block-size: var(--greese-input-height);
|
|
13
22
|
padding-inline: var(--greese-input-padding);
|
|
14
23
|
cursor: text;
|
|
@@ -47,6 +56,26 @@
|
|
|
47
56
|
}
|
|
48
57
|
}
|
|
49
58
|
|
|
59
|
+
// `htmlSize`: as wide as that many characters and no wider, so the frame
|
|
60
|
+
// hugs the input rather than stretching or shrinking. The doubled class
|
|
61
|
+
// beats a container's `flex: 1 1 auto` (EditableField's control slot, a
|
|
62
|
+
// toolbar row) without depending on which stylesheet the bundle happens to
|
|
63
|
+
// emit last.
|
|
64
|
+
.greese-Input.greese-Input--measured {
|
|
65
|
+
inline-size: fit-content;
|
|
66
|
+
|
|
67
|
+
// Neither grows nor gives up its measure in a crowded row.
|
|
68
|
+
flex: none;
|
|
69
|
+
|
|
70
|
+
// `size` alone measures in the font's average character, narrower than
|
|
71
|
+
// its digits, so seven of them overflow `size="7"`. `--greese-input-size`
|
|
72
|
+
// (set by the React component) measures in `ch`; without it, `size` rules.
|
|
73
|
+
.greese-Input-control {
|
|
74
|
+
flex: none;
|
|
75
|
+
inline-size: calc(var(--greese-input-size) * 1ch);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
50
79
|
@each $size, $spec in controls.$sizes {
|
|
51
80
|
.greese-Input--size-#{$size} {
|
|
52
81
|
--greese-input-height: #{map.get($spec, height)};
|
|
@@ -20,6 +20,24 @@
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
// A context menu is a Menu surface with a different anchor, so it carries
|
|
24
|
+
// `greese-Menu` too and changes only what the anchor implies.
|
|
25
|
+
.greese-ContextMenu {
|
|
26
|
+
// Menu's width floor makes a dropdown look deliberate under the button
|
|
27
|
+
// that opened it. A context menu has no button: it appears at the pointer,
|
|
28
|
+
// so it should be exactly as wide as its own items.
|
|
29
|
+
min-inline-size: 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// The stand-in for the pointer position: a zero-size box a ContextMenu
|
|
33
|
+
// anchors to. Inert and never painted — only its position matters.
|
|
34
|
+
.greese-ContextMenu-point {
|
|
35
|
+
position: fixed;
|
|
36
|
+
inline-size: 0;
|
|
37
|
+
block-size: 0;
|
|
38
|
+
pointer-events: none;
|
|
39
|
+
}
|
|
40
|
+
|
|
23
41
|
.greese-Menu-viewport {
|
|
24
42
|
min-block-size: 0;
|
|
25
43
|
padding: var(--greese-space-1);
|
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
font-variant-numeric: tabular-nums;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
// Two carets in a column, the height of the field between them. Side by side
|
|
9
|
+
// they cost about 3.5rem of a field's width, which is most of a row in a
|
|
10
|
+
// dense panel; stacked they cost one button's width.
|
|
8
11
|
.greese-NumberField-steppers {
|
|
9
12
|
display: inline-flex;
|
|
10
|
-
|
|
11
|
-
margin-inline-end: calc(-1 * var(--greese-space-
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
margin-inline-end: calc(-1 * var(--greese-space-1));
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
.greese-NumberField-step {
|
|
@@ -17,8 +20,6 @@
|
|
|
17
20
|
position: relative;
|
|
18
21
|
display: inline-grid;
|
|
19
22
|
place-items: center;
|
|
20
|
-
inline-size: 1.75rem;
|
|
21
|
-
block-size: 1.75rem;
|
|
22
23
|
padding: 0;
|
|
23
24
|
color: var(--greese-color-fg-muted);
|
|
24
25
|
cursor: pointer;
|
|
@@ -26,11 +27,6 @@
|
|
|
26
27
|
border: 0;
|
|
27
28
|
border-radius: var(--greese-corner-inset);
|
|
28
29
|
|
|
29
|
-
> svg {
|
|
30
|
-
inline-size: 1rem;
|
|
31
|
-
block-size: 1rem;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
30
|
@include mixins.hover {
|
|
35
31
|
color: var(--greese-color-fg);
|
|
36
32
|
background-color: color-mix(in oklab, var(--greese-color-fg) 8%, transparent);
|
|
@@ -41,4 +37,55 @@
|
|
|
41
37
|
opacity: 0.4;
|
|
42
38
|
}
|
|
43
39
|
}
|
|
40
|
+
|
|
41
|
+
// Stacked: each caret takes half the row, so the pair is one button tall.
|
|
42
|
+
.greese-NumberField-steppers .greese-NumberField-step {
|
|
43
|
+
inline-size: 1.25rem;
|
|
44
|
+
block-size: 0.875rem;
|
|
45
|
+
|
|
46
|
+
> svg {
|
|
47
|
+
inline-size: 0.75rem;
|
|
48
|
+
block-size: 0.75rem;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Split: a minus at one end of the field and a plus at the other, each a
|
|
53
|
+
// full-height target.
|
|
54
|
+
.greese-NumberField--split .greese-NumberField-step {
|
|
55
|
+
inline-size: 1.5rem;
|
|
56
|
+
block-size: 1.5rem;
|
|
57
|
+
|
|
58
|
+
> svg {
|
|
59
|
+
inline-size: 0.875rem;
|
|
60
|
+
block-size: 0.875rem;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// The × that empties the field: a small, muted target inside its end.
|
|
65
|
+
.greese-NumberField-clear {
|
|
66
|
+
@include mixins.touch-target;
|
|
67
|
+
|
|
68
|
+
position: relative;
|
|
69
|
+
display: inline-grid;
|
|
70
|
+
flex: none;
|
|
71
|
+
place-items: center;
|
|
72
|
+
inline-size: 1.25rem;
|
|
73
|
+
block-size: 1.25rem;
|
|
74
|
+
padding: 0;
|
|
75
|
+
color: var(--greese-color-fg-muted);
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
background: none;
|
|
78
|
+
border: 0;
|
|
79
|
+
border-radius: var(--greese-corner-round);
|
|
80
|
+
|
|
81
|
+
@include mixins.hover {
|
|
82
|
+
color: var(--greese-color-fg);
|
|
83
|
+
background-color: color-mix(in oklab, var(--greese-color-fg) 8%, transparent);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
> svg {
|
|
87
|
+
inline-size: 0.75rem;
|
|
88
|
+
block-size: 0.75rem;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
44
91
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@layer greese.components {
|
|
2
|
+
// A minus at one end and a plus at the other, with the value between them.
|
|
3
|
+
// The field keeps its own frame; only what sits inside it differs from a
|
|
4
|
+
// NumberField.
|
|
5
|
+
.greese-NumberStepper {
|
|
6
|
+
--greese-numberstepper-gap: var(--greese-space-1);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// The value is centred because it reads as a quantity, not as typed text.
|
|
10
|
+
.greese-NumberStepper .greese-Input-control {
|
|
11
|
+
text-align: center;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
// greese-PageTransition--still not animated at all
|
|
14
14
|
// greese-PageTransition--page a whole page: only its screenful shows
|
|
15
15
|
// greese-PageTransition--left a page that left live: its rest fades
|
|
16
|
+
// greese-PageTransition--route-enter, --route-exit, --route-pace
|
|
17
|
+
// a route's or navigation's own effects
|
|
18
|
+
// and pace, read from the root's
|
|
19
|
+
// --greese-page-enter / -exit /
|
|
20
|
+
// -duration / -ease (usePageNavigate)
|
|
16
21
|
// Transition types (`greese-back`, …) pick between these classes in React's
|
|
17
22
|
// <ViewTransition> props, which works wherever React does; the CSS doesn't
|
|
18
23
|
// depend on `:active-view-transition-type()`. Entrances play the effects' own
|
|
@@ -93,6 +98,30 @@
|
|
|
93
98
|
animation-name: none;
|
|
94
99
|
}
|
|
95
100
|
|
|
101
|
+
// A route's or a navigation's own effects (usePageNavigate writes the
|
|
102
|
+
// variables at the click): after the named effects and the theme's roles,
|
|
103
|
+
// so they win; `--left` below still wins, since a live exit already played.
|
|
104
|
+
html::view-transition-new(*.greese-PageTransition--route-enter) {
|
|
105
|
+
animation-name: var(--greese-page-enter);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
html::view-transition-old(*.greese-PageTransition--route-exit) {
|
|
109
|
+
animation-name: var(--greese-page-exit);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
html::view-transition-group(*.greese-PageTransition--route-pace),
|
|
113
|
+
html::view-transition-old(*.greese-PageTransition--route-pace),
|
|
114
|
+
html::view-transition-new(*.greese-PageTransition--route-pace) {
|
|
115
|
+
animation-duration: var(
|
|
116
|
+
--greese-page-duration,
|
|
117
|
+
var(--greese-motion-page-duration, var(--greese-duration-normal))
|
|
118
|
+
);
|
|
119
|
+
animation-timing-function: var(
|
|
120
|
+
--greese-page-ease,
|
|
121
|
+
var(--greese-motion-page-ease, var(--greese-ease-out))
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
96
125
|
// A shared element morphs from where it was to where it is: its group
|
|
97
126
|
// moves and resizes, at the theme's `share-duration` and `share-ease`.
|
|
98
127
|
html::view-transition-group(*.greese-PageTransition--share) {
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
@include mixins.touch-target;
|
|
6
6
|
|
|
7
7
|
position: relative;
|
|
8
|
-
inline-size: 1.125rem;
|
|
9
|
-
block-size: 1.125rem;
|
|
8
|
+
inline-size: var(--greese-choice-box, 1.125rem);
|
|
9
|
+
block-size: var(--greese-choice-box, 1.125rem);
|
|
10
10
|
margin: 0;
|
|
11
11
|
cursor: pointer;
|
|
12
12
|
background-color: var(--greese-color-canvas);
|