contain-css-svelte 1.4.3 → 1.6.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/dist/Card.svelte +57 -3
- package/dist/controls/Button.svelte +32 -0
- package/dist/controls/ButtonLink.svelte +32 -0
- package/dist/controls/Checkbox.svelte +36 -0
- package/dist/controls/CircleButton.svelte +32 -0
- package/dist/controls/GroupedRadioItem.svelte +551 -0
- package/dist/controls/GroupedRadioItem.svelte.d.ts +36 -0
- package/dist/controls/GroupedToggle.svelte +147 -0
- package/dist/controls/GroupedToggle.svelte.d.ts +9 -0
- package/dist/controls/GroupedToggleItem.svelte +452 -0
- package/dist/controls/GroupedToggleItem.svelte.d.ts +31 -0
- package/dist/controls/Input.svelte +32 -0
- package/dist/controls/RadioButton.svelte +36 -1
- package/dist/controls/Select.svelte +80 -2
- package/dist/controls/Slider.svelte +32 -0
- package/dist/controls/TabItem.svelte +36 -0
- package/dist/controls/Toggle.svelte +32 -0
- package/dist/dropdowns/DropdownMenu.svelte +53 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/layout/Accordion.svelte +32 -0
- package/dist/layout/Bar.svelte +50 -0
- package/dist/layout/ColumnContainer.svelte +32 -0
- package/dist/layout/Columns.svelte +32 -0
- package/dist/layout/Container.svelte +48 -2
- package/dist/layout/DataList.svelte +33 -1
- package/dist/layout/DataList.svelte.d.ts +7 -0
- package/dist/layout/DataListItem.svelte +56 -2
- package/dist/layout/Fieldset.svelte +32 -0
- package/dist/layout/Form.svelte +32 -0
- package/dist/layout/FormItem.svelte +46 -0
- package/dist/layout/GridLayout.svelte +59 -0
- package/dist/layout/Hero.svelte +42 -0
- package/dist/layout/Inline.svelte +37 -1
- package/dist/layout/MenuList.svelte +32 -0
- package/dist/layout/Page.svelte +137 -10
- package/dist/layout/Page.svelte.d.ts +17 -0
- package/dist/layout/RowContainer.svelte +32 -0
- package/dist/layout/Sidebar.svelte +104 -56
- package/dist/layout/SidebarContainer.svelte +32 -0
- package/dist/layout/SplitPane.svelte +32 -0
- package/dist/layout/Stack.svelte +32 -0
- package/dist/layout/TabBar.svelte +127 -8
- package/dist/layout/TabBar.svelte.d.ts +16 -0
- package/dist/layout/Table.svelte +60 -9
- package/dist/layout/Tile.svelte +89 -6
- package/dist/misc/CodeInner.svelte +32 -0
- package/dist/misc/Progress.svelte +32 -0
- package/dist/misc/Tag.svelte +32 -0
- package/dist/overlays/Dialog.svelte +32 -0
- package/dist/overlays/Tooltip.svelte +32 -0
- package/dist/sass/_responsive.scss +43 -0
- package/dist/typography/TextLayout.svelte +47 -0
- package/dist/vars/defaults.css +4 -1
- package/dist/vars/layout.css +4 -1
- package/dist/vars/responsive-typography.css +4 -1
- package/package.json +1 -1
|
@@ -86,6 +86,38 @@ const el = $derived(elementProps(restProps, "input", INPUT_VARS));
|
|
|
86
86
|
we deliberately avoid everywhere else.
|
|
87
87
|
|
|
88
88
|
One definition, used by both, so they cannot drift again. */
|
|
89
|
+
/* The "small" size tier: a component whose container is this wide or less
|
|
90
|
+
is on a phone, or in a pane about that narrow, and sizes itself for it.
|
|
91
|
+
|
|
92
|
+
The convention, shared by every component that has a size worth changing
|
|
93
|
+
there (Card started it; Tile, GridLayout, Bar and Container follow):
|
|
94
|
+
|
|
95
|
+
--{component}-{property}-small
|
|
96
|
+
|
|
97
|
+
applies inside a small container. What wins there, in order:
|
|
98
|
+
1. the `-small` variable, if you set it;
|
|
99
|
+
2. otherwise the regular variable, if you set it -- a size you chose on
|
|
100
|
+
purpose is not overridden behind your back;
|
|
101
|
+
3. otherwise the component's own small default, which for most
|
|
102
|
+
properties is simply its regular default.
|
|
103
|
+
|
|
104
|
+
Container queries can't read a custom property, so the breakpoint itself
|
|
105
|
+
is fixed here rather than themeable. 600px matches Card and SplitPane,
|
|
106
|
+
which already switched there. (The Sidebar's rail-to-sheet switch,
|
|
107
|
+
above, is a separate, layout-chrome decision and keeps its own value.) */
|
|
108
|
+
/* Styles for the small tier: the nearest container is narrow, OR the
|
|
109
|
+
viewport is.
|
|
110
|
+
|
|
111
|
+
The container query is the real answer -- a Tile in a 400px pane on a
|
|
112
|
+
desktop is small. But a container query only matches inside an ancestor
|
|
113
|
+
that *is* a container, and a component dropped straight into a page (no
|
|
114
|
+
Page, no Container around it) has none, so on a phone it would never
|
|
115
|
+
find out. The viewport query covers that: a narrow viewport means every
|
|
116
|
+
container in it is narrow too, so the two never disagree in the
|
|
117
|
+
direction that matters.
|
|
118
|
+
|
|
119
|
+
An element never queries itself, so on a component that is its own
|
|
120
|
+
container (Tile, Bar) this asks about the space it was given. */
|
|
89
121
|
/* Warning: because we define a fallback
|
|
90
122
|
media query, the media query can override the container
|
|
91
123
|
if we stack a bunch of these in a row and aren't thoughtful about the order.
|
|
@@ -113,6 +113,38 @@ function handleChange() {
|
|
|
113
113
|
we deliberately avoid everywhere else.
|
|
114
114
|
|
|
115
115
|
One definition, used by both, so they cannot drift again. */
|
|
116
|
+
/* The "small" size tier: a component whose container is this wide or less
|
|
117
|
+
is on a phone, or in a pane about that narrow, and sizes itself for it.
|
|
118
|
+
|
|
119
|
+
The convention, shared by every component that has a size worth changing
|
|
120
|
+
there (Card started it; Tile, GridLayout, Bar and Container follow):
|
|
121
|
+
|
|
122
|
+
--{component}-{property}-small
|
|
123
|
+
|
|
124
|
+
applies inside a small container. What wins there, in order:
|
|
125
|
+
1. the `-small` variable, if you set it;
|
|
126
|
+
2. otherwise the regular variable, if you set it -- a size you chose on
|
|
127
|
+
purpose is not overridden behind your back;
|
|
128
|
+
3. otherwise the component's own small default, which for most
|
|
129
|
+
properties is simply its regular default.
|
|
130
|
+
|
|
131
|
+
Container queries can't read a custom property, so the breakpoint itself
|
|
132
|
+
is fixed here rather than themeable. 600px matches Card and SplitPane,
|
|
133
|
+
which already switched there. (The Sidebar's rail-to-sheet switch,
|
|
134
|
+
above, is a separate, layout-chrome decision and keeps its own value.) */
|
|
135
|
+
/* Styles for the small tier: the nearest container is narrow, OR the
|
|
136
|
+
viewport is.
|
|
137
|
+
|
|
138
|
+
The container query is the real answer -- a Tile in a 400px pane on a
|
|
139
|
+
desktop is small. But a container query only matches inside an ancestor
|
|
140
|
+
that *is* a container, and a component dropped straight into a page (no
|
|
141
|
+
Page, no Container around it) has none, so on a phone it would never
|
|
142
|
+
find out. The viewport query covers that: a narrow viewport means every
|
|
143
|
+
container in it is narrow too, so the two never disagree in the
|
|
144
|
+
direction that matters.
|
|
145
|
+
|
|
146
|
+
An element never queries itself, so on a component that is its own
|
|
147
|
+
container (Tile, Bar) this asks about the space it was given. */
|
|
116
148
|
/* Warning: because we define a fallback
|
|
117
149
|
media query, the media query can override the container
|
|
118
150
|
if we stack a bunch of these in a row and aren't thoughtful about the order.
|
|
@@ -123,6 +155,10 @@ function handleChange() {
|
|
|
123
155
|
.label-sizing-box {
|
|
124
156
|
position: relative;
|
|
125
157
|
display: inline-block;
|
|
158
|
+
/* An inline-block wraps as a whole first, so short labels in a row just
|
|
159
|
+
flow onto the next line; only a label longer than the whole row wraps
|
|
160
|
+
its own text (the invisible sizer and the real label wrap alike). */
|
|
161
|
+
max-width: 100%;
|
|
126
162
|
}
|
|
127
163
|
|
|
128
164
|
.label-sizing-box .radio-item {
|
|
@@ -176,7 +212,6 @@ label.radio-item {
|
|
|
176
212
|
box-sizing: border-box;
|
|
177
213
|
user-select: none;
|
|
178
214
|
gap: var(--radio-button-space, var(--toggle-space, var(--space-md)));
|
|
179
|
-
white-space: nowrap;
|
|
180
215
|
cursor: var(--radio-button-cursor, var(--clickable-cursor, var(--cursor, pointer)));
|
|
181
216
|
}
|
|
182
217
|
|
|
@@ -18,6 +18,9 @@ let observer;
|
|
|
18
18
|
let resizeObserver;
|
|
19
19
|
let targetWidth = $state("");
|
|
20
20
|
let optionButtons = $state([]);
|
|
21
|
+
// The subset of optionButtons the resize observer is currently watching, so
|
|
22
|
+
// the $effect below can tell "nothing changed" from "rewire".
|
|
23
|
+
let observedButtons = [];
|
|
21
24
|
onMount(() => {
|
|
22
25
|
tick().then(() => updateOptions());
|
|
23
26
|
/*
|
|
@@ -40,14 +43,37 @@ onMount(() => {
|
|
|
40
43
|
attributeFilter: ["data-html", "value", "label", "selected"],
|
|
41
44
|
});
|
|
42
45
|
}
|
|
43
|
-
// Observe size changes in option buttons
|
|
44
46
|
resizeObserver = new ResizeObserver(() => updateTargetWidth());
|
|
45
|
-
optionButtons.forEach((button) => resizeObserver.observe(button));
|
|
46
47
|
return () => {
|
|
47
48
|
observer.disconnect();
|
|
48
49
|
resizeObserver.disconnect();
|
|
49
50
|
};
|
|
50
51
|
});
|
|
52
|
+
/*
|
|
53
|
+
optionButtons is populated by `bind:this` inside the {#each options}
|
|
54
|
+
block below, so it only ever reflects the CURRENT option list once Svelte
|
|
55
|
+
has reconciled the DOM -- which happens asynchronously relative to the
|
|
56
|
+
updateOptions() call that rebuilt `options`. Re-deriving the observed set
|
|
57
|
+
here, every time that binding changes, is what keeps the ResizeObserver
|
|
58
|
+
in sync in both directions: a button added once the list grows longer
|
|
59
|
+
gets observed, and one removed when the list shrinks is dropped instead
|
|
60
|
+
of lingering as a stale (and eventually null) target.
|
|
61
|
+
|
|
62
|
+
Guarded by reference comparison so an unrelated re-render that leaves the
|
|
63
|
+
same buttons in place doesn't thrash disconnect()/observe() every time.
|
|
64
|
+
*/
|
|
65
|
+
$effect(() => {
|
|
66
|
+
if (!resizeObserver)
|
|
67
|
+
return;
|
|
68
|
+
const current = optionButtons.filter((button) => Boolean(button));
|
|
69
|
+
const unchanged = current.length === observedButtons.length &&
|
|
70
|
+
current.every((button, i) => button === observedButtons[i]);
|
|
71
|
+
if (unchanged)
|
|
72
|
+
return;
|
|
73
|
+
resizeObserver.disconnect();
|
|
74
|
+
current.forEach((button) => resizeObserver.observe(button));
|
|
75
|
+
observedButtons = current;
|
|
76
|
+
});
|
|
51
77
|
let options = $state([]);
|
|
52
78
|
let activeOption = $state(null);
|
|
53
79
|
let updateQueued = false;
|
|
@@ -73,12 +99,29 @@ function updateOptions() {
|
|
|
73
99
|
html: richHtml.trim(),
|
|
74
100
|
});
|
|
75
101
|
}
|
|
102
|
+
/*
|
|
103
|
+
optionButtons is bound by index from the {#each options} block below,
|
|
104
|
+
so when the option list shrinks, the array's tail is left holding
|
|
105
|
+
targets for <li>s that no longer render. (Svelte nulls each removed
|
|
106
|
+
binding's own slot as it tears the element down, but that happens once
|
|
107
|
+
the DOM catches up with this reassignment, not synchronously here --
|
|
108
|
+
so truncate now rather than leave the old length around in the
|
|
109
|
+
meantime.) Trimming it here, before the {#each} re-renders, keeps it
|
|
110
|
+
from ever describing more options than currently exist.
|
|
111
|
+
*/
|
|
112
|
+
if (optionButtons.length > options.length) {
|
|
113
|
+
optionButtons.length = options.length;
|
|
114
|
+
}
|
|
76
115
|
activeOption = options[selectElement.selectedIndex];
|
|
77
116
|
updateTargetWidth();
|
|
78
117
|
}
|
|
79
118
|
function updateTargetWidth() {
|
|
80
119
|
let maxWidth = 0;
|
|
81
120
|
for (let button of optionButtons) {
|
|
121
|
+
// A stale or not-yet-bound slot (see updateOptions() above) -- skip it
|
|
122
|
+
// rather than crash on a null bind:this target.
|
|
123
|
+
if (!button)
|
|
124
|
+
continue;
|
|
82
125
|
if (button.offsetWidth > maxWidth) {
|
|
83
126
|
maxWidth = button.offsetWidth;
|
|
84
127
|
}
|
|
@@ -212,6 +255,38 @@ $effect(() => {
|
|
|
212
255
|
we deliberately avoid everywhere else.
|
|
213
256
|
|
|
214
257
|
One definition, used by both, so they cannot drift again. */
|
|
258
|
+
/* The "small" size tier: a component whose container is this wide or less
|
|
259
|
+
is on a phone, or in a pane about that narrow, and sizes itself for it.
|
|
260
|
+
|
|
261
|
+
The convention, shared by every component that has a size worth changing
|
|
262
|
+
there (Card started it; Tile, GridLayout, Bar and Container follow):
|
|
263
|
+
|
|
264
|
+
--{component}-{property}-small
|
|
265
|
+
|
|
266
|
+
applies inside a small container. What wins there, in order:
|
|
267
|
+
1. the `-small` variable, if you set it;
|
|
268
|
+
2. otherwise the regular variable, if you set it -- a size you chose on
|
|
269
|
+
purpose is not overridden behind your back;
|
|
270
|
+
3. otherwise the component's own small default, which for most
|
|
271
|
+
properties is simply its regular default.
|
|
272
|
+
|
|
273
|
+
Container queries can't read a custom property, so the breakpoint itself
|
|
274
|
+
is fixed here rather than themeable. 600px matches Card and SplitPane,
|
|
275
|
+
which already switched there. (The Sidebar's rail-to-sheet switch,
|
|
276
|
+
above, is a separate, layout-chrome decision and keeps its own value.) */
|
|
277
|
+
/* Styles for the small tier: the nearest container is narrow, OR the
|
|
278
|
+
viewport is.
|
|
279
|
+
|
|
280
|
+
The container query is the real answer -- a Tile in a 400px pane on a
|
|
281
|
+
desktop is small. But a container query only matches inside an ancestor
|
|
282
|
+
that *is* a container, and a component dropped straight into a page (no
|
|
283
|
+
Page, no Container around it) has none, so on a phone it would never
|
|
284
|
+
find out. The viewport query covers that: a narrow viewport means every
|
|
285
|
+
container in it is narrow too, so the two never disagree in the
|
|
286
|
+
direction that matters.
|
|
287
|
+
|
|
288
|
+
An element never queries itself, so on a component that is its own
|
|
289
|
+
container (Tile, Bar) this asks about the space it was given. */
|
|
215
290
|
/* Warning: because we define a fallback
|
|
216
291
|
media query, the media query can override the container
|
|
217
292
|
if we stack a bunch of these in a row and aren't thoughtful about the order.
|
|
@@ -318,6 +393,9 @@ select,
|
|
|
318
393
|
background-color: var(--_background-color);
|
|
319
394
|
color: var(--_color);
|
|
320
395
|
width: var(--select-width, var(--target-width, var(--dropdown-menu-width, min(12em, 100vw))));
|
|
396
|
+
/* The measured width fits the longest option; the container may be
|
|
397
|
+
narrower than that. Truncate (below) rather than overflow. */
|
|
398
|
+
max-width: 100%;
|
|
321
399
|
text-overflow: ellipsis;
|
|
322
400
|
font-family: var(--select-font-family, var(--input-font-family, var(--ui-font-family, var(--font-family, unset))));
|
|
323
401
|
text-transform: var(--select-text-transform, var(--input-text-transform, var(--ui-text-transform, var(--text-transform, unset))));
|
|
@@ -88,6 +88,38 @@ const el = $derived(elementProps(restProps, "slider", ["bg", "fg", "padding", "w
|
|
|
88
88
|
we deliberately avoid everywhere else.
|
|
89
89
|
|
|
90
90
|
One definition, used by both, so they cannot drift again. */
|
|
91
|
+
/* The "small" size tier: a component whose container is this wide or less
|
|
92
|
+
is on a phone, or in a pane about that narrow, and sizes itself for it.
|
|
93
|
+
|
|
94
|
+
The convention, shared by every component that has a size worth changing
|
|
95
|
+
there (Card started it; Tile, GridLayout, Bar and Container follow):
|
|
96
|
+
|
|
97
|
+
--{component}-{property}-small
|
|
98
|
+
|
|
99
|
+
applies inside a small container. What wins there, in order:
|
|
100
|
+
1. the `-small` variable, if you set it;
|
|
101
|
+
2. otherwise the regular variable, if you set it -- a size you chose on
|
|
102
|
+
purpose is not overridden behind your back;
|
|
103
|
+
3. otherwise the component's own small default, which for most
|
|
104
|
+
properties is simply its regular default.
|
|
105
|
+
|
|
106
|
+
Container queries can't read a custom property, so the breakpoint itself
|
|
107
|
+
is fixed here rather than themeable. 600px matches Card and SplitPane,
|
|
108
|
+
which already switched there. (The Sidebar's rail-to-sheet switch,
|
|
109
|
+
above, is a separate, layout-chrome decision and keeps its own value.) */
|
|
110
|
+
/* Styles for the small tier: the nearest container is narrow, OR the
|
|
111
|
+
viewport is.
|
|
112
|
+
|
|
113
|
+
The container query is the real answer -- a Tile in a 400px pane on a
|
|
114
|
+
desktop is small. But a container query only matches inside an ancestor
|
|
115
|
+
that *is* a container, and a component dropped straight into a page (no
|
|
116
|
+
Page, no Container around it) has none, so on a phone it would never
|
|
117
|
+
find out. The viewport query covers that: a narrow viewport means every
|
|
118
|
+
container in it is narrow too, so the two never disagree in the
|
|
119
|
+
direction that matters.
|
|
120
|
+
|
|
121
|
+
An element never queries itself, so on a component that is its own
|
|
122
|
+
container (Tile, Bar) this asks about the space it was given. */
|
|
91
123
|
/* Warning: because we define a fallback
|
|
92
124
|
media query, the media query can override the container
|
|
93
125
|
if we stack a bunch of these in a row and aren't thoughtful about the order.
|
|
@@ -100,6 +100,38 @@ const el = $derived(elementProps(restProps, "tab", [
|
|
|
100
100
|
we deliberately avoid everywhere else.
|
|
101
101
|
|
|
102
102
|
One definition, used by both, so they cannot drift again. */
|
|
103
|
+
/* The "small" size tier: a component whose container is this wide or less
|
|
104
|
+
is on a phone, or in a pane about that narrow, and sizes itself for it.
|
|
105
|
+
|
|
106
|
+
The convention, shared by every component that has a size worth changing
|
|
107
|
+
there (Card started it; Tile, GridLayout, Bar and Container follow):
|
|
108
|
+
|
|
109
|
+
--{component}-{property}-small
|
|
110
|
+
|
|
111
|
+
applies inside a small container. What wins there, in order:
|
|
112
|
+
1. the `-small` variable, if you set it;
|
|
113
|
+
2. otherwise the regular variable, if you set it -- a size you chose on
|
|
114
|
+
purpose is not overridden behind your back;
|
|
115
|
+
3. otherwise the component's own small default, which for most
|
|
116
|
+
properties is simply its regular default.
|
|
117
|
+
|
|
118
|
+
Container queries can't read a custom property, so the breakpoint itself
|
|
119
|
+
is fixed here rather than themeable. 600px matches Card and SplitPane,
|
|
120
|
+
which already switched there. (The Sidebar's rail-to-sheet switch,
|
|
121
|
+
above, is a separate, layout-chrome decision and keeps its own value.) */
|
|
122
|
+
/* Styles for the small tier: the nearest container is narrow, OR the
|
|
123
|
+
viewport is.
|
|
124
|
+
|
|
125
|
+
The container query is the real answer -- a Tile in a 400px pane on a
|
|
126
|
+
desktop is small. But a container query only matches inside an ancestor
|
|
127
|
+
that *is* a container, and a component dropped straight into a page (no
|
|
128
|
+
Page, no Container around it) has none, so on a phone it would never
|
|
129
|
+
find out. The viewport query covers that: a narrow viewport means every
|
|
130
|
+
container in it is narrow too, so the two never disagree in the
|
|
131
|
+
direction that matters.
|
|
132
|
+
|
|
133
|
+
An element never queries itself, so on a component that is its own
|
|
134
|
+
container (Tile, Bar) this asks about the space it was given. */
|
|
103
135
|
/* Warning: because we define a fallback
|
|
104
136
|
media query, the media query can override the container
|
|
105
137
|
if we stack a bunch of these in a row and aren't thoughtful about the order.
|
|
@@ -238,6 +270,10 @@ const el = $derived(elementProps(restProps, "tab", [
|
|
|
238
270
|
.tab > :global(div > button) {
|
|
239
271
|
border-radius: var(--tab-border-radius, var(--border-radius) var(--border-radius) 0 0);
|
|
240
272
|
margin: 0;
|
|
273
|
+
/* In a TabBar that scrolls, a tab keeps its label on one line and its
|
|
274
|
+
full width; squeezing the labels is what made them wrap. */
|
|
275
|
+
flex-shrink: 0;
|
|
276
|
+
white-space: nowrap;
|
|
241
277
|
}
|
|
242
278
|
|
|
243
279
|
.tab.active > :global(button),
|
|
@@ -117,6 +117,38 @@ const effectiveOnLabel = $derived(onLabel || children);
|
|
|
117
117
|
we deliberately avoid everywhere else.
|
|
118
118
|
|
|
119
119
|
One definition, used by both, so they cannot drift again. */
|
|
120
|
+
/* The "small" size tier: a component whose container is this wide or less
|
|
121
|
+
is on a phone, or in a pane about that narrow, and sizes itself for it.
|
|
122
|
+
|
|
123
|
+
The convention, shared by every component that has a size worth changing
|
|
124
|
+
there (Card started it; Tile, GridLayout, Bar and Container follow):
|
|
125
|
+
|
|
126
|
+
--{component}-{property}-small
|
|
127
|
+
|
|
128
|
+
applies inside a small container. What wins there, in order:
|
|
129
|
+
1. the `-small` variable, if you set it;
|
|
130
|
+
2. otherwise the regular variable, if you set it -- a size you chose on
|
|
131
|
+
purpose is not overridden behind your back;
|
|
132
|
+
3. otherwise the component's own small default, which for most
|
|
133
|
+
properties is simply its regular default.
|
|
134
|
+
|
|
135
|
+
Container queries can't read a custom property, so the breakpoint itself
|
|
136
|
+
is fixed here rather than themeable. 600px matches Card and SplitPane,
|
|
137
|
+
which already switched there. (The Sidebar's rail-to-sheet switch,
|
|
138
|
+
above, is a separate, layout-chrome decision and keeps its own value.) */
|
|
139
|
+
/* Styles for the small tier: the nearest container is narrow, OR the
|
|
140
|
+
viewport is.
|
|
141
|
+
|
|
142
|
+
The container query is the real answer -- a Tile in a 400px pane on a
|
|
143
|
+
desktop is small. But a container query only matches inside an ancestor
|
|
144
|
+
that *is* a container, and a component dropped straight into a page (no
|
|
145
|
+
Page, no Container around it) has none, so on a phone it would never
|
|
146
|
+
find out. The viewport query covers that: a narrow viewport means every
|
|
147
|
+
container in it is narrow too, so the two never disagree in the
|
|
148
|
+
direction that matters.
|
|
149
|
+
|
|
150
|
+
An element never queries itself, so on a component that is its own
|
|
151
|
+
container (Tile, Bar) this asks about the space it was given. */
|
|
120
152
|
/* Warning: because we define a fallback
|
|
121
153
|
media query, the media query can override the container
|
|
122
154
|
if we stack a bunch of these in a row and aren't thoughtful about the order.
|
|
@@ -255,7 +255,9 @@ let popoverDiv = $state();
|
|
|
255
255
|
aria-expanded={isOpen ? "true" : "false"}
|
|
256
256
|
aria-controls={id}
|
|
257
257
|
>
|
|
258
|
-
|
|
258
|
+
<span class="trigger-label"
|
|
259
|
+
>{#if label}{@render label()}{:else}Menu{/if}</span
|
|
260
|
+
>
|
|
259
261
|
</button>
|
|
260
262
|
<div
|
|
261
263
|
{id}
|
|
@@ -358,6 +360,38 @@ let popoverDiv = $state();
|
|
|
358
360
|
we deliberately avoid everywhere else.
|
|
359
361
|
|
|
360
362
|
One definition, used by both, so they cannot drift again. */
|
|
363
|
+
/* The "small" size tier: a component whose container is this wide or less
|
|
364
|
+
is on a phone, or in a pane about that narrow, and sizes itself for it.
|
|
365
|
+
|
|
366
|
+
The convention, shared by every component that has a size worth changing
|
|
367
|
+
there (Card started it; Tile, GridLayout, Bar and Container follow):
|
|
368
|
+
|
|
369
|
+
--{component}-{property}-small
|
|
370
|
+
|
|
371
|
+
applies inside a small container. What wins there, in order:
|
|
372
|
+
1. the `-small` variable, if you set it;
|
|
373
|
+
2. otherwise the regular variable, if you set it -- a size you chose on
|
|
374
|
+
purpose is not overridden behind your back;
|
|
375
|
+
3. otherwise the component's own small default, which for most
|
|
376
|
+
properties is simply its regular default.
|
|
377
|
+
|
|
378
|
+
Container queries can't read a custom property, so the breakpoint itself
|
|
379
|
+
is fixed here rather than themeable. 600px matches Card and SplitPane,
|
|
380
|
+
which already switched there. (The Sidebar's rail-to-sheet switch,
|
|
381
|
+
above, is a separate, layout-chrome decision and keeps its own value.) */
|
|
382
|
+
/* Styles for the small tier: the nearest container is narrow, OR the
|
|
383
|
+
viewport is.
|
|
384
|
+
|
|
385
|
+
The container query is the real answer -- a Tile in a 400px pane on a
|
|
386
|
+
desktop is small. But a container query only matches inside an ancestor
|
|
387
|
+
that *is* a container, and a component dropped straight into a page (no
|
|
388
|
+
Page, no Container around it) has none, so on a phone it would never
|
|
389
|
+
find out. The viewport query covers that: a narrow viewport means every
|
|
390
|
+
container in it is narrow too, so the two never disagree in the
|
|
391
|
+
direction that matters.
|
|
392
|
+
|
|
393
|
+
An element never queries itself, so on a component that is its own
|
|
394
|
+
container (Tile, Bar) this asks about the space it was given. */
|
|
361
395
|
/* Warning: because we define a fallback
|
|
362
396
|
media query, the media query can override the container
|
|
363
397
|
if we stack a bunch of these in a row and aren't thoughtful about the order.
|
|
@@ -497,6 +531,20 @@ button:focus-visible {
|
|
|
497
531
|
|
|
498
532
|
button {
|
|
499
533
|
position: relative;
|
|
534
|
+
/* In a crowded row (a toolbar, a phone-width header) the trigger gives
|
|
535
|
+
way before its neighbours do: never wider than the space it was given,
|
|
536
|
+
its label on one line and truncated with an ellipsis (below). */
|
|
537
|
+
max-width: 100%;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/* The clipping lives on this inner span, not the button: overflow other
|
|
541
|
+
than visible moves an inline-level box's baseline to its bottom edge,
|
|
542
|
+
which would drop the trigger out of line with text beside it. */
|
|
543
|
+
.trigger-label {
|
|
544
|
+
display: block;
|
|
545
|
+
white-space: nowrap;
|
|
546
|
+
overflow: hidden;
|
|
547
|
+
text-overflow: ellipsis;
|
|
500
548
|
}
|
|
501
549
|
|
|
502
550
|
.dropdown-content :global(.menu) {
|
|
@@ -993,6 +1041,10 @@ button {
|
|
|
993
1041
|
|
|
994
1042
|
nav {
|
|
995
1043
|
position: relative;
|
|
1044
|
+
/* Lets a flex/grid parent shrink the menu below its label's width, so the
|
|
1045
|
+
trigger's ellipsis can kick in instead of the row overflowing. */
|
|
1046
|
+
min-width: 0;
|
|
1047
|
+
max-width: 100%;
|
|
996
1048
|
}
|
|
997
1049
|
|
|
998
1050
|
[popover] {
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,9 @@ import Button from "./controls/Button.svelte";
|
|
|
4
4
|
import ButtonLink from "./controls/ButtonLink.svelte";
|
|
5
5
|
import Checkbox from "./controls/Checkbox.svelte";
|
|
6
6
|
import CircleButton from "./controls/CircleButton.svelte";
|
|
7
|
+
import GroupedToggle from "./controls/GroupedToggle.svelte";
|
|
8
|
+
import GroupedToggleItem from "./controls/GroupedToggleItem.svelte";
|
|
9
|
+
import GroupedRadioItem from "./controls/GroupedRadioItem.svelte";
|
|
7
10
|
import Input from "./controls/Input.svelte";
|
|
8
11
|
import MiniButton from "./controls/MiniButton.svelte";
|
|
9
12
|
import RadioButton from "./controls/RadioButton.svelte";
|
|
@@ -51,6 +54,7 @@ export type { BaseStyleProps, MarginStyleProps, ContainerStyleProps, BarStylePro
|
|
|
51
54
|
export { Tag };
|
|
52
55
|
export { Hero };
|
|
53
56
|
export { TabItem };
|
|
57
|
+
export { GroupedToggle, GroupedToggleItem, GroupedRadioItem };
|
|
54
58
|
export { Button, ButtonLink, CircleButton, Checkbox, Input, Slider, Toggle, RadioButton, MiniButton, Select, Option, };
|
|
55
59
|
export { Bar, ColumnContainer, Container, GridLayout, GridRow, Inline, MenuList, Page, ResponsiveText, RowContainer, Stack, TabBar, };
|
|
56
60
|
export { TextLayout, Code, Accordion };
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,9 @@ import Button from "./controls/Button.svelte";
|
|
|
5
5
|
import ButtonLink from "./controls/ButtonLink.svelte";
|
|
6
6
|
import Checkbox from "./controls/Checkbox.svelte";
|
|
7
7
|
import CircleButton from "./controls/CircleButton.svelte";
|
|
8
|
+
import GroupedToggle from "./controls/GroupedToggle.svelte";
|
|
9
|
+
import GroupedToggleItem from "./controls/GroupedToggleItem.svelte";
|
|
10
|
+
import GroupedRadioItem from "./controls/GroupedRadioItem.svelte";
|
|
8
11
|
import Input from "./controls/Input.svelte";
|
|
9
12
|
import MiniButton from "./controls/MiniButton.svelte";
|
|
10
13
|
import RadioButton from "./controls/RadioButton.svelte";
|
|
@@ -51,6 +54,7 @@ import Text from "./typography/Text.svelte";
|
|
|
51
54
|
export { Tag };
|
|
52
55
|
export { Hero };
|
|
53
56
|
export { TabItem };
|
|
57
|
+
export { GroupedToggle, GroupedToggleItem, GroupedRadioItem };
|
|
54
58
|
export { Button, ButtonLink, CircleButton, Checkbox, Input, Slider, Toggle, RadioButton, MiniButton, Select, Option, };
|
|
55
59
|
export { Bar, ColumnContainer, Container, GridLayout, GridRow, Inline, MenuList, Page, ResponsiveText, RowContainer, Stack, TabBar, };
|
|
56
60
|
export { TextLayout, Code, Accordion };
|
|
@@ -124,6 +124,38 @@ function onAccordionClicked(e) {
|
|
|
124
124
|
we deliberately avoid everywhere else.
|
|
125
125
|
|
|
126
126
|
One definition, used by both, so they cannot drift again. */
|
|
127
|
+
/* The "small" size tier: a component whose container is this wide or less
|
|
128
|
+
is on a phone, or in a pane about that narrow, and sizes itself for it.
|
|
129
|
+
|
|
130
|
+
The convention, shared by every component that has a size worth changing
|
|
131
|
+
there (Card started it; Tile, GridLayout, Bar and Container follow):
|
|
132
|
+
|
|
133
|
+
--{component}-{property}-small
|
|
134
|
+
|
|
135
|
+
applies inside a small container. What wins there, in order:
|
|
136
|
+
1. the `-small` variable, if you set it;
|
|
137
|
+
2. otherwise the regular variable, if you set it -- a size you chose on
|
|
138
|
+
purpose is not overridden behind your back;
|
|
139
|
+
3. otherwise the component's own small default, which for most
|
|
140
|
+
properties is simply its regular default.
|
|
141
|
+
|
|
142
|
+
Container queries can't read a custom property, so the breakpoint itself
|
|
143
|
+
is fixed here rather than themeable. 600px matches Card and SplitPane,
|
|
144
|
+
which already switched there. (The Sidebar's rail-to-sheet switch,
|
|
145
|
+
above, is a separate, layout-chrome decision and keeps its own value.) */
|
|
146
|
+
/* Styles for the small tier: the nearest container is narrow, OR the
|
|
147
|
+
viewport is.
|
|
148
|
+
|
|
149
|
+
The container query is the real answer -- a Tile in a 400px pane on a
|
|
150
|
+
desktop is small. But a container query only matches inside an ancestor
|
|
151
|
+
that *is* a container, and a component dropped straight into a page (no
|
|
152
|
+
Page, no Container around it) has none, so on a phone it would never
|
|
153
|
+
find out. The viewport query covers that: a narrow viewport means every
|
|
154
|
+
container in it is narrow too, so the two never disagree in the
|
|
155
|
+
direction that matters.
|
|
156
|
+
|
|
157
|
+
An element never queries itself, so on a component that is its own
|
|
158
|
+
container (Tile, Bar) this asks about the space it was given. */
|
|
127
159
|
/* Warning: because we define a fallback
|
|
128
160
|
media query, the media query can override the container
|
|
129
161
|
if we stack a bunch of these in a row and aren't thoughtful about the order.
|
package/dist/layout/Bar.svelte
CHANGED
|
@@ -119,6 +119,38 @@ const el = $derived(elementProps({ ...restProps, marginTop, marginBottom }, "bar
|
|
|
119
119
|
we deliberately avoid everywhere else.
|
|
120
120
|
|
|
121
121
|
One definition, used by both, so they cannot drift again. */
|
|
122
|
+
/* The "small" size tier: a component whose container is this wide or less
|
|
123
|
+
is on a phone, or in a pane about that narrow, and sizes itself for it.
|
|
124
|
+
|
|
125
|
+
The convention, shared by every component that has a size worth changing
|
|
126
|
+
there (Card started it; Tile, GridLayout, Bar and Container follow):
|
|
127
|
+
|
|
128
|
+
--{component}-{property}-small
|
|
129
|
+
|
|
130
|
+
applies inside a small container. What wins there, in order:
|
|
131
|
+
1. the `-small` variable, if you set it;
|
|
132
|
+
2. otherwise the regular variable, if you set it -- a size you chose on
|
|
133
|
+
purpose is not overridden behind your back;
|
|
134
|
+
3. otherwise the component's own small default, which for most
|
|
135
|
+
properties is simply its regular default.
|
|
136
|
+
|
|
137
|
+
Container queries can't read a custom property, so the breakpoint itself
|
|
138
|
+
is fixed here rather than themeable. 600px matches Card and SplitPane,
|
|
139
|
+
which already switched there. (The Sidebar's rail-to-sheet switch,
|
|
140
|
+
above, is a separate, layout-chrome decision and keeps its own value.) */
|
|
141
|
+
/* Styles for the small tier: the nearest container is narrow, OR the
|
|
142
|
+
viewport is.
|
|
143
|
+
|
|
144
|
+
The container query is the real answer -- a Tile in a 400px pane on a
|
|
145
|
+
desktop is small. But a container query only matches inside an ancestor
|
|
146
|
+
that *is* a container, and a component dropped straight into a page (no
|
|
147
|
+
Page, no Container around it) has none, so on a phone it would never
|
|
148
|
+
find out. The viewport query covers that: a narrow viewport means every
|
|
149
|
+
container in it is narrow too, so the two never disagree in the
|
|
150
|
+
direction that matters.
|
|
151
|
+
|
|
152
|
+
An element never queries itself, so on a component that is its own
|
|
153
|
+
container (Tile, Bar) this asks about the space it was given. */
|
|
122
154
|
/* Warning: because we define a fallback
|
|
123
155
|
media query, the media query can override the container
|
|
124
156
|
if we stack a bunch of these in a row and aren't thoughtful about the order.
|
|
@@ -256,6 +288,24 @@ const el = $derived(elementProps({ ...restProps, marginTop, marginBottom }, "bar
|
|
|
256
288
|
--_heading-margin-inline: var-with-fallbacks(--heading-margin-inline, bar, 0);
|
|
257
289
|
}
|
|
258
290
|
|
|
291
|
+
/* Small tier (see $small-max): --bar-padding-small, --bar-gap-small and
|
|
292
|
+
--bar-min-height-small, each falling back to the regular value. A bar
|
|
293
|
+
that should be slimmer on a phone says so once, here, instead of every
|
|
294
|
+
consumer writing its own query. */
|
|
295
|
+
@media (max-width: 600px) {
|
|
296
|
+
.bar {
|
|
297
|
+
padding: var(--bar-padding-small, var(--bar-padding, var(--padding, 8px)));
|
|
298
|
+
gap: var(--bar-gap-small, var(--bar-gap, var(--gap, 8px)));
|
|
299
|
+
min-height: var(--bar-min-height-small, var(--bar-min-height, var(--bar-height, 3em)));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
@container (max-width: 600px) {
|
|
303
|
+
.bar {
|
|
304
|
+
padding: var(--bar-padding-small, var(--bar-padding, var(--padding, 8px)));
|
|
305
|
+
gap: var(--bar-gap-small, var(--bar-gap, var(--gap, 8px)));
|
|
306
|
+
min-height: var(--bar-min-height-small, var(--bar-min-height, var(--bar-height, 3em)));
|
|
307
|
+
}
|
|
308
|
+
}
|
|
259
309
|
.bar :global(h1),
|
|
260
310
|
.bar :global(h2),
|
|
261
311
|
.bar :global(h3),
|
|
@@ -92,6 +92,38 @@ const el = $derived(elementProps(restProps, "column-container", COLUMN_CONTAINER
|
|
|
92
92
|
we deliberately avoid everywhere else.
|
|
93
93
|
|
|
94
94
|
One definition, used by both, so they cannot drift again. */
|
|
95
|
+
/* The "small" size tier: a component whose container is this wide or less
|
|
96
|
+
is on a phone, or in a pane about that narrow, and sizes itself for it.
|
|
97
|
+
|
|
98
|
+
The convention, shared by every component that has a size worth changing
|
|
99
|
+
there (Card started it; Tile, GridLayout, Bar and Container follow):
|
|
100
|
+
|
|
101
|
+
--{component}-{property}-small
|
|
102
|
+
|
|
103
|
+
applies inside a small container. What wins there, in order:
|
|
104
|
+
1. the `-small` variable, if you set it;
|
|
105
|
+
2. otherwise the regular variable, if you set it -- a size you chose on
|
|
106
|
+
purpose is not overridden behind your back;
|
|
107
|
+
3. otherwise the component's own small default, which for most
|
|
108
|
+
properties is simply its regular default.
|
|
109
|
+
|
|
110
|
+
Container queries can't read a custom property, so the breakpoint itself
|
|
111
|
+
is fixed here rather than themeable. 600px matches Card and SplitPane,
|
|
112
|
+
which already switched there. (The Sidebar's rail-to-sheet switch,
|
|
113
|
+
above, is a separate, layout-chrome decision and keeps its own value.) */
|
|
114
|
+
/* Styles for the small tier: the nearest container is narrow, OR the
|
|
115
|
+
viewport is.
|
|
116
|
+
|
|
117
|
+
The container query is the real answer -- a Tile in a 400px pane on a
|
|
118
|
+
desktop is small. But a container query only matches inside an ancestor
|
|
119
|
+
that *is* a container, and a component dropped straight into a page (no
|
|
120
|
+
Page, no Container around it) has none, so on a phone it would never
|
|
121
|
+
find out. The viewport query covers that: a narrow viewport means every
|
|
122
|
+
container in it is narrow too, so the two never disagree in the
|
|
123
|
+
direction that matters.
|
|
124
|
+
|
|
125
|
+
An element never queries itself, so on a component that is its own
|
|
126
|
+
container (Tile, Bar) this asks about the space it was given. */
|
|
95
127
|
/* Warning: because we define a fallback
|
|
96
128
|
media query, the media query can override the container
|
|
97
129
|
if we stack a bunch of these in a row and aren't thoughtful about the order.
|
|
@@ -78,6 +78,38 @@ const el = $derived(elementProps(restProps, "columns", ["gap"]));
|
|
|
78
78
|
we deliberately avoid everywhere else.
|
|
79
79
|
|
|
80
80
|
One definition, used by both, so they cannot drift again. */
|
|
81
|
+
/* The "small" size tier: a component whose container is this wide or less
|
|
82
|
+
is on a phone, or in a pane about that narrow, and sizes itself for it.
|
|
83
|
+
|
|
84
|
+
The convention, shared by every component that has a size worth changing
|
|
85
|
+
there (Card started it; Tile, GridLayout, Bar and Container follow):
|
|
86
|
+
|
|
87
|
+
--{component}-{property}-small
|
|
88
|
+
|
|
89
|
+
applies inside a small container. What wins there, in order:
|
|
90
|
+
1. the `-small` variable, if you set it;
|
|
91
|
+
2. otherwise the regular variable, if you set it -- a size you chose on
|
|
92
|
+
purpose is not overridden behind your back;
|
|
93
|
+
3. otherwise the component's own small default, which for most
|
|
94
|
+
properties is simply its regular default.
|
|
95
|
+
|
|
96
|
+
Container queries can't read a custom property, so the breakpoint itself
|
|
97
|
+
is fixed here rather than themeable. 600px matches Card and SplitPane,
|
|
98
|
+
which already switched there. (The Sidebar's rail-to-sheet switch,
|
|
99
|
+
above, is a separate, layout-chrome decision and keeps its own value.) */
|
|
100
|
+
/* Styles for the small tier: the nearest container is narrow, OR the
|
|
101
|
+
viewport is.
|
|
102
|
+
|
|
103
|
+
The container query is the real answer -- a Tile in a 400px pane on a
|
|
104
|
+
desktop is small. But a container query only matches inside an ancestor
|
|
105
|
+
that *is* a container, and a component dropped straight into a page (no
|
|
106
|
+
Page, no Container around it) has none, so on a phone it would never
|
|
107
|
+
find out. The viewport query covers that: a narrow viewport means every
|
|
108
|
+
container in it is narrow too, so the two never disagree in the
|
|
109
|
+
direction that matters.
|
|
110
|
+
|
|
111
|
+
An element never queries itself, so on a component that is its own
|
|
112
|
+
container (Tile, Bar) this asks about the space it was given. */
|
|
81
113
|
/* Warning: because we define a fallback
|
|
82
114
|
media query, the media query can override the container
|
|
83
115
|
if we stack a bunch of these in a row and aren't thoughtful about the order.
|